Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Limited sorting. 2

Status
Not open for further replies.

Daedelus

Technical User
Aug 14, 2002
70
0
0
US
I have a file I would like to sort by 1 field, while otherwise leaving the order alone. For example if the original file is:
2 B
1 B
2 A
3 A
4 D
3 D
I would like it sorted as:
2 A
3 A
2 B
1 B
4 D
3 D

But no matter how I try to limit the sorting field of "sort", within the indicated sort it will always sort by the rest of the line:
2 A
3 A
1 B
2 B
3 D
4 D

Is there some trick I am missing that will limit the sort to only the indicated fields, and preserve the original order otherwise? Or will I have to do it the hard way?
 
I dont think you are missing any trick,you have to go the hard way.
You have to write your own sorting finction which uses the second parameter i.e. A,A,B,B,D etc as primary keys and the linenumber of each of them as the secondary key.
amit
crazy_indian@lycos.com

to bug is human to debug devine
 
Apparently, a side effect of sort is causing your problem. All sort knows is that it sorted by the second column - just what you asked for. Amit is right; you aren't missing
anything, but I think there's a better way than writing your own sort. Adding another column can preserve the integrity of column 1.

Execute:

pr -n -t data.file > e.1

provides file e.1:

1 2 B
2 1 B
3 2 A
4 3 A
5 4 D
6 3 D

Now, sort by field 3 (originally field 2) and field 1 (the added field):

sort -k 3 -k 1 e.1

should provide your output, plus the additional column.

Of course, for production, eliminate the temp file and print out just the columns you want:

pr -n -t data.file|sort -k 3 -k 1|awk ' { printf("%s %s\n", $2, $3) } '

yeah, I know! Not only is it inefficient, but it just sucks, but we do what we have to.

Regards,


Ed
 
Here's a solution in perl but it's not much prettier that what Ed posted. I don't think its guaranteed to work either because it relies on the fact the the Perl sort() keeps the fields in their original order if they are equal (i don't know if this is true or not). It works for the data that you posted, though.
Code:
perl -e 'print map{join&quot; &quot;,@$_,&quot;\n&quot;}sort{$a->[1]cmp$b->[1]}map{[split]}<>' datafile

jaa
 
Cool find Ed,I kept searching for the same solution but I wasn't able to find out how to print the line number, I tried the ed command but I coudn't make it work. A star for you.

How about
pr -n -t data.file|sort -k 3 | sed s/^[0-9]* /&quot;&quot;/g
(Not tested)
We can remove the -k 1 for some more optimisation and replace awk by sed so we can handle a variable number of strings in the file.

cheers
amit
crazy_indian@lycos.com

to bug is human to debug devine
 
the sed statement is:

s/^SPACE[SPACE]*[1-9][0-9]*TAB//
 
Thanks to you all! That is just what I needed. My actual situation (which is of course much more complicated than the file I gave, but I couldn't show it to you without upsetting the lawyers!), lends itself easily to the extra processing, so that is really not a problem. Thanks again!
 
First, thanks for the stars.

Amit:

If I were going for flexibility, and wanted to remain with awk, I would set up a for loop from 2 to NF for each line piped to awk.

Since sed has a smaller foot print than awk, I'll take a look at the awk solutions posted. I'm still climbing the sed learning curve.

Again, thanks!

Ed
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top