Sort complex data

Hi,

Can someone here help sorting the following data in numeric order?

INPUT:
FIRST abc(3) def(13) fgh(1) ijk(6) abc(2)
SECOND dfe(10) abc(4) hij(19) tlm(1) hij(1) hub(10) abc(1) fed(3)
OTHERS hij(10) mok(4) bub(19) hij(1) abc(2) abc(15) abc(1) hij(3)

OUTPUT:
FIRST def(13) ijk(6) abc(3) abc(2) fgh(1)
SECOND hij(19) dfe(10) hub(10) abc(4) fed(3) abc(1) hij(1) tlm(1)
OTHERS bub(19) abc(15) hij(10) mok(4) hij(3) abc(2) abc(1) hij(1)

Thanks in advance for your help!!!

That output is tricky, since it seems to be sorting in two different directions, alphabetically but reverse-numerically... commandline sort can't do that, you'd be writing your own shell-based sorting routines. Is the form of the output really that strict? What's the data for?

Are you sorting each line by the number in () in descending order?

The data is from CVS log and I only care about the number, not alphabetic.
All I want to do is sort numers in each row.

Thanks!

Yes. Need to sort numbers in descending order in each line.

Thank you!

Here's some code that could probably be more efficient but I think does what you want:

#!/bin/sh

while read TITLE LINE
do
        ARR=( $LINE )
        for ((N=0; N<${#ARR}; N++))
        do
                if [[ -z "${ARR[$N]}" ]]
                then
                        break
                fi

                OLDIFS="${IFS}"
                IFS="()"
                VAL=( ${ARR[$N]} )

                printf "%s %s\n" ${VAL[1]} ${VAL[0]}
                IFS="${OLDIFS}"
        done | sort -rn | (
                echo -n $TITLE
                while read I STR
                do
                        echo -n " ${STR}(${I})"
                done
                echo    )
done

exit 0
$ echo "FIRST abc(3) def(13) fgh(1) ijk(6) abc(2)
SECOND dfe(10) abc(4) hij(19) tlm(1) hij(1) hub(10) abc(1) fed(3)
OTHERS hij(10) mok(4) bub(19) hij(1) abc(2) abc(15) abc(1) hij(3)" | ./sorter.sh
FIRST def(13) ijk(6) abc(3) abc(2) fgh(1)
SECOND hij(19) hub(10) dfe(10) abc(4) tlm(1) hij(1) abc(1)
OTHERS bub(19) abc(15) hij(10) mok(4) abc(2) hij(1) abc(1)
$

It failed at line "ARR=( $LINE )".
syntax error at line 5: `ARR=' unexpected

need_help - what shell are you using? show the result from

echo $SHELL

Try /bin/bash instead of /bin/sh. I keep forgetting that plain sh doesn't always support "advanced" things like.. sigh.. arrays..

> cat file167
FIRST abc(3) def(13) fgh(1) ijk(6) abc(2)
SECOND dfe(10) abc(4) hij(19) tlm(1) hij(1) hub(10) abc(1) fed(3)
OTHERS hij(10) mok(4) bub(19) hij(1) abc(2) abc(15) abc(1) hij(3)

> cat sort167.sh
#!/usr/bin/bash

while read header data
   do
#   echo $header
#   echo $data
    revdata=`echo $data | tr " " "\n" | sort -rn +0.4 | tr "\n" " "`

    echo $header $revdata

done <file167

> sort167.sh
FIRST def(13) ijk(6) abc(3) abc(2) fgh(1)
SECOND hij(19) hub(10) dfe(10) abc(4) fed(3) tlm(1) hij(1) abc(1)
OTHERS bub(19) abc(15) hij(10) mok(4) hij(3) abc(2) hij(1) abc(1)

With Perl:

perl -lane'
    print join " ", shift @F, sort {
        ($aa) = $a =~ /(\d+)/;
        ($bb) = $b =~ /(\d+)/;
        $bb <=> $aa
      } @F
  ' infile

hi, i think perl should be a right and easy solution.

#!/usr/bin/perl
sub sub_sort{
	my @t1=split("[(|)]",$_[0]);
	my @t2=split("[(|)]",$_[1]);
	if($t1[1] == $t2[1]){
		return $t1[0] cmp $t2[0];
	}
	else{
		return $t2[1] <=> $t1[1];
	}
}
open FH,"<a.txt";
while(<FH>){
	chomp;
	my @temp=split(" ",$_);
	print $temp[0]," ", join " ",sort { sub_sort($a,$b) } @temp[1..$#temp];
	print "\n";
}

Nice catch summer_cherry, I did not notice that the OP wants to sort twice (first numeric, then ascii/utf8), so I need to modify the code:

perl -lane'
    print join " ", shift @F, sort {
        ($aa) = $a =~ /(\d+)/;
        ($bb) = $b =~ /(\d+)/;
        $bb <=> $aa || $a cmp $b
      } @F
  ' infile