Sort the file contents in each group....print the group title as well

I've this file and need to sort the data in each group

File would look like this ...

cat file1.txt

Reason : ABC
12345-0023
32123-5400
32442-5333

Reason : DEF
42523-3453
23345-3311

Reason : HIJ
454553-0001

I would like to sort each group on the last 4 fileds and print them in the same group

I want the file to look like this

Reason : ABC
12345-0023
32442-5333
32123-5400


Reason : DEF
23345-3311
42523-3453


Reason : HIJ
454553-0001

I tried using the sort command but it would mess up the group.. any hints or ideas would be appriciated too....

Thanks in advance

Before you can sort it, you must first break them into separate groups.

---------- Post updated at 01:57 PM ---------- Previous update was at 01:46 PM ----------

This is a bit of a kludge since the sort command doesn't seem to be able to sort based on anything but fixed column positions, and your first column is variable size. If we swap the data around, it can always sort based on the first four columns.

#!/bin/sh

while read LINE
do
        # First line of a group
        if [ "${LINE:0:6}" == "Reason" ]
        then
                # Print the header
                echo "${LINE}"
                # Keep looping until we hit a blank line.
                while IFS="-" read A B && [ ! -z "${A}" ]
                do
                        # Reverse the order of the items so they can be sorted
                        echo "${B}-${A}"
                done | sort -u --key=1,4 |
                # Reverse the order back
                while IFS="-" read B A
                do
                        echo "${A}-${B}"
                done

                # Add a blank line to the end.
                echo
        fi
done < data
1 Like
awk -vRS="" '{system("echo \""$0"\" |sort -n -t- -k2");print ""}' file

Another way:

sed '/^$/d' TestGroup.txt | \
gawk 'BEGIN{arrayIndex=0}
{
	if($1 == "Reason")
	{
		if(arrayIndex != 0)
		{
			arrayElements = asort(myArray)
			for(i=1; i <= arrayElements; i++)
			{
				print myArray
			}
		}
		print $0
		arrayIndex=0
		delete myArray
	}
	else
	{
		myArray[arrayIndex]=$0
		arrayIndex++
	}
}END{
		if(arrayIndex != 0)
		{
			arrayElements = asort(myArray)
			for(i=1; i <= arrayElements; i++)
			{
				print myArray
			}
		}
	}'
1 Like
while read -r l; do if [[ "$l" != "" ]] ; then echo "$l">>tmp ; else sort -t- -k2n tmp; echo "" ; rm -f tmp ; fi ; done<infile ; more tmp ; rm -f tmp
Reason : ABC
12345-0023
32442-5333
32123-5400
 
Reason : DEF
23345-3311
42523-3453
 
Reason : HIJ
454553-0001
1 Like

Ah, so setting RS="" makes awk break records apart on blank lines. So you can just read in records one by one and sort them. Nice!

Thanks you all.

But this one was perfect.

You guys are the best.

---------- Post updated 08-25-10 at 09:23 AM ---------- Previous update was 08-24-10 at 04:23 PM ----------

A good question to Bartus...

I tried your command as well but it prints nothing but the blank lines ...

Can you please explain the command or fix it please?

Then maybe your real input data is different from what you provided as sample, couse my code works OK on your sample data (at least in my environment).

May be its environments... I am using the Solaris.

$ cat file1.txt
Reason : ABC
12345-0023
32123-5400
32442-5333

Reason : DEF
42523-3453
23345-3311

Reason : HIJ
454553-0001
$ awk -vRS="" '{system("echo \""$0"\" |sort -n -t- -k2");print ""}' file1.txt











$

Thanks for your quick reply.

---------- Post updated at 09:43 AM ---------- Previous update was at 09:39 AM ----------

Never mind Bartus..

I got it ...

awk -vRS="" '{system("echo \""$0"\" |sort -n -t- -k2");print}' file1.txt

Removed the "" after the print and it worked great.

Thanks ...

Well in my Solaris 10 environment, i had to do this to make it work:

nawk  'BEGIN{RS=""}{system("echo \""$0"\" |sort -n -t- -k2");print ""}' file
1 Like

Always warn people of that first! :wink:

local $/="\n\n";
while(<DATA>){
  my @tmp = split("\n",$_);
  print $tmp[0],"\n";
  print join "\n", map {$_->[0]} sort {$a->[1]<=>$b->[1]} map {my @t=split("-",$_);[$_,$t[1]]} @tmp[1..$#tmp];
  print "\n\n";
}
__DATA__
Reason : ABC
12345-0023
32123-5400
32442-5333

Reason : DEF
42523-3453
23345-3311

Reason : HIJ
454553-0001