cmo
cmo

Reputation: 4104

sort fields within a line

input:

87    6,1,9,13
3     9,4,14,35,38,13
31    3,1,6,5

(i.e. a tab-delimited column where the second field is a comma-delimited list of unordered integers.)

desired output:

87    1,6,9,13
3     4,9,13,14,35,38
31    1,3,5,6

Goal:
for each line separately, sort the comma-separated list appearing in the second field. i.e. sort the 2nd column within for each line separately.

Note: the rows should not be re-ordered.

What I've tried:

sort - Since the order of the rows should not change, then sort is simply not applicable.

awk - since the greater file is tab-delimited, not comma-delimited, it cannot parse the second column as multiple "sub-fields"

There might be a perl way? I know nothing about perl though...

Upvotes: 1

Views: 1010

Answers (3)

user3665322
user3665322

Reputation: 165

Another way: echo happybirthday|awk '{split($0,A);asort(A); for (i=1;i<length(A);i++) {print A[i]}}' FS=""|tr -d '\n';echo aabdhhipprty

I didn't know how to get back to this page after recovering login info, so am posting as a guest.

Upvotes: 0

Hynek -Pichi- Vychodil
Hynek -Pichi- Vychodil

Reputation: 26121

It can be done by simple perl oneliner:

perl -F'/\t/' -alne'$s=join",",sort{$a<=>$b}split",",$F[1];print"$F[0]\t$s"'

and shell (bash) one as well:

while read a b;do echo -e "$a\t$(echo $b|tr , '\n'|sort -n|tr '\n' ,|sed 's/,$//')"; done

Upvotes: 2

Manny D
Manny D

Reputation: 20714

while read LINE; do 
   echo -e "$(echo $LINE | awk '{print $1}')\t$(echo $LINE | awk '{print $2}' | tr ',' '\n' | sort -n | paste -s -d,)"; 
done < input

Obviously a lot going on here so here we go:

  • input contains your input
  • $(echo $LINE | awk '{print $1}') prints the first field, pretty straightforward
  • $(echo $LINE | awk '{print $2}' | tr ',' '\n' | sort -n | paste -s -d,) prints the second field, but breaks it down into lines by replacing the commas by newlines (tr ',' '\n'), then sort numerically, then assemble the lines back to comma-delimited values (paste -s -d,).

$ cat input
87    6,1,9,13
3     9,4,14,35,38,13
31    3,1,6,5

$ while read LINE; do echo -e "$(echo $LINE | awk '{print $1}')\t$(echo $LINE | awk '{print $2}' | tr ',' '\n' | sort -n | paste -s -d,)"; done < input
87      1,6,9,13
3       4,9,13,14,35,38
31      1,3,5,6

Upvotes: 1

Related Questions