4

I am trying to sort all values of a list and add them, sorted, into another list . The sort -nu works fine but he doesn't want to add $i to the new SortedList. What could be the problem here?

function Sort() {
   SortedList=""
   for i in $list;
   do
      echo $i
      $SortedList= "$SortedList $i"
   done | sort -nu
}

echo " This is the sorted list : $SortedList"

5
  • The line $SortedList= "$SortedList $i" should be SortedList="$SortedList $i". A $ and a space less. But I guess that wouldn't be enough. Commented May 29, 2015 at 9:26
  • Even with that fixed, I don't understand how SortedList could be sorted at the end... The pipe won't change the iteration order. Commented May 29, 2015 at 9:28
  • Yes, thats why I edited my comment. You just append i to the sorted list and therefore it will become a copy of list. Commented May 29, 2015 at 9:30
  • Can you show a sample input and expected output? Commented May 29, 2015 at 9:30
  • The problem is the pipe to the sort command. Without the pipe it works fine. I suspect the for command is due to the pipe executed in different shell. Commented May 29, 2015 at 9:31

2 Answers 2

4

I think you can do something like the following.

#!/bin/bash
list="7 4 2 5 3"

function Sort() {
    SortedList=$(echo $list | tr " " "\n" | sort -nu)
}
Sort
echo $SortedList

It may fail because we still don't know how your list looks like.

Sign up to request clarification or add additional context in comments.

1 Comment

To avoid an UUCA you could write it like: SortedList=$(tr " " "\n" <<<"${list}" | sort -nu).
0

Your solution tries to store the list items to the SortedList before the sort itself. The echo $i part sends the list to the pipe and the sort -nu then prints it (sorted) to the STDOUT. If you want to store the sorted list to the variable, just try this:

function Sort() {
    SortedList=`for i in $list; do echo $i; done | sort -nu`
}

If you're wondering why the SortedList variable is empty after the function call, the problem is the pipe to the sort command. Without the pipe it works fine. From wiki:

In the most commonly used simple pipelines the shell connects a series of sub-processes via pipes, and executes external commands within each sub-process. Thus the shell itself is doing no direct processing of the data flowing through the pipeline.

That means the for part of the pipe starts a new sub-process (with the sorted var initialized), that changes the sorted variable as it is supposed to. But, when the process ends, you are back in the environment with the initial value of the variable.

Also, consult this post (Set a parent shell's variable from a subshell)

12 Comments

Okay, thank you. I understand the problem. Do you know a way to use the variable in the whole script?
According to the SO post, there is no way to alter a variable inside a sub-shell, so you can try to do this via the file, or you can do the for-loop twice, first time it will only set the variable, and second time put the output to the pipe.
Thank you, he still gives me the error "= 5: command not found" on this line : $SortedList="$SortedList $i"
you must remove the first dollar (SortedList="$SortesList $i") otherwise for the first time it interprets the $SortedList as an empty string followed by the "= 5" string, which is then interpreted as a (non existing) command.
sorry, I had the typo in the code too. Edited and fixed.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.