Reputation: 69
third try to understand what Im doing wrong.
Ive got a list like this:
array[0] = 1111 Here is much text
array[1] = 2222 Here is even more text
array[2] = 1111.1 Here is special text
Now I want to sort the list to have it like this:
1111 Here is much text
1111.1 Here is special text
2222 Here is even more text
Using
for j in ${array[@]}; do echo $j; done | sort -n
it seperates me every single part because of the spaces.
Using
for j in "${array[@]}"; do echo "$j"; done | sort -n
I get a sorted list like 1111 2222 1111.1
Upvotes: 0
Views: 120
Reputation: 247012
array=(
"1111 Here is much text"
"2222 Here is even more text"
"1111.1 Here is special text"
)
printf "%s\n" "${array[@]}" | sort -n
1111 Here is much text
1111.1 Here is special text
2222 Here is even more text
To save it:
sorted=()
while IFS= read -r line; do
sorted+=("$line")
done < <( printf "%s\n" "${array[@]}" | sort -n )
printf "%s\n" "${sorted[@]}"
# same output as above
or
source <( echo 'sorted=('; printf '"%s"\n' "${array[@]}" | sort -n; echo ')' )
printf "%s\n" "${sorted[@]}"
Carriage returns in your file will mess you up. Consider file named "t" with dos-style line endings:
$ cat -e t
line1^M$
line2^M$
line3^M$
$ for n in {1..3} ; do array[n]="$(echo $n $(cat t))"; done
$ printf "%s\n" "${array[@]}"|od -c
0000000 1 l i n e 1 \r l i n e 2 \r
0000020 l i n e 3 \r \n 2 l i n e 1 \r
0000040 l i n e 2 \r l i n e 3 \r \n 3
0000060 l i n e 1 \r l i n e 2 \r l i
0000100 n e 3 \r \n
0000105
$ printf "%s\n" "${array[@]}"
line31
line31
line31
Clearly this is going to mess up anything you feed with this input. Fix the carriage returns.
Upvotes: 3
Reputation: 728
Your locale is set in such a way that the .
is interpreted as a thousands separator, rather than a decimal point, and the numeric values are sorted accordingly (1111.1 is interpreteted as 11111, e.g. with LC_ALL=de_DE
). Use
export LC_ALL=C
before you execute sort
(and, of course, use proper quoting, as in glenn's and fedorqui's answers).
Upvotes: 0