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"

anubhava
  • 761,203
  • 64
  • 569
  • 643
Mathias Verhoeven
  • 927
  • 2
  • 10
  • 24
  • The line `$SortedList= "$SortedList $i"` should be `SortedList="$SortedList $i"`. A $ and a space less. But I guess that wouldn't be enough. – Rambo Ramon May 29 '15 at 09: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. – Maxime Chéramy May 29 '15 at 09: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. – Rambo Ramon May 29 '15 at 09:30
  • Can you show a sample input and expected output? – choroba May 29 '15 at 09: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. – Jindra Helcl May 29 '15 at 09:31

2 Answers2

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.

Rambo Ramon
  • 1,034
  • 7
  • 10
  • 1
    To avoid an [UUCA](http://porkmail.org/era/unix/award.html) you could write it like: `SortedList=$(tr " " "\n" <<<"${list}" | sort -nu)`. – Lohmar ASHAR Jan 20 '21 at 20:00
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)

Community
  • 1
  • 1
Jindra Helcl
  • 3,457
  • 1
  • 20
  • 26
  • Okay, thank you. I understand the problem. Do you know a way to use the variable in the whole script? – Mathias Verhoeven May 29 '15 at 09:44
  • 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. – Jindra Helcl May 29 '15 at 10:04
  • Thank you, he still gives me the error "= 5: command not found" on this line : $SortedList="$SortedList $i" – Mathias Verhoeven May 29 '15 at 10:25
  • 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. – Jindra Helcl May 29 '15 at 10:48
  • sorry, I had the typo in the code too. Edited and fixed. – Jindra Helcl May 29 '15 at 10:51
  • I still do not see at which point this is supposed to sort anything. After the loop `SortedList` is identical to `list`. After that you echo this list and write it to a temporary file. Nothing is piped to `sort` because the output of the echo is written to the file. Then, you read the file again, but its content was not modified. I mean you neither tried your solution (otherwise you would have found the typo way earlier) nor thought it through. – Rambo Ramon May 29 '15 at 11:51
  • The question was referring to the problem that the SortedList variable is not filled with anything. The list in this variable is of course in the same order as it was on the input. However, the sorted ĺist is written to `STDOUT`. And you are wrong about that nothing is piped to the sort. There are two `echo` commands there, take a closer look. One is going to the pipe, and the other is going to the file. – Jindra Helcl May 29 '15 at 11:55
  • As for you judging whether I tried the solution - I wrote an one-liner in my shell and then (after i found out that it worked), I copied the original code and make my changes to it. The solution may not do what @MathiasVerhoeven intended, but surely, it answers the asked question. – Jindra Helcl May 29 '15 at 11:57
  • Then your one-liner has nothing to do with the code you posted. Try it: http://www.tutorialspoint.com/execute_bash_online.php?PID=0Bw_CjBb95KQMSzRKMVk2X256N2M It does not print the sorted order and `SortedList` is still unsorted. – Rambo Ramon May 29 '15 at 12:05
  • You're right.. I didn't check if the outputted list is sorted. – Jindra Helcl May 29 '15 at 12:09
  • Your last edit looks ok to me. I have not tried it but it should work. – Rambo Ramon May 29 '15 at 12:14
  • Yeah, I was originally more interested in the assignment-in-subprocess part of the problem so I didn't pay too much attention to solving the rest. – Jindra Helcl May 29 '15 at 12:18