How to sort multiple lines in bash?

I am trying to sort a list of names followed by another line, for example:

John Doe AVAIL Sara Doe CALL Jim Doe AVAIL 

I am trying to sort them by name, but cannot figure out what it looks like. Can someone give some recommendations?

My end result will look like this:

 Jim Doe AVAIL John Doe AVAIL Sara Doe CALL 

Very valuable!

+7
source share
3 answers

Probably far from optimal, but

 sed -r ':r;/(^|\n)$/!{$!{N;br}};s/\n/\v/g' names | sort | sed 's/\v/\n/g' 

seems to be doing the job ( names is a file with entries). This allows you to record an arbitrary length, not just two lines.

+6
source

Not sure if this will work for you, but with some limitations, here is a line that does what you need.

 awk '{if ((NR%2-1)==0) {line=sprintf("%-30s",$0)} else {print line ":" $0}}' | \ sort --key=1,30 | tr ':' '\n' 

Assumptions: there are no empty lines between entries, the name is always less than 30 characters, and the text does not use :

I am sure that you can understand how to change it if the assumptions are different.

In a nutshell, it concatenates two lines, using ':' as a separator, padding the first line up to 30 characters and sorting using the first 30 characters. Then he breaks the lines.

0
source

not directly, but you can use some intermediate form like this. I assume your value (CALL, AVAIL, etc.) is limited. otherwise you need to use more complex patterns, but you can do it. in fact, everything can be done in bash :-)

 cat sorting | sed -n '1h; 1!H; ${ g; s/\nCALL\n/::CALL::/g; s/\nAVAIL\n/::AVAIL::/g ; s/\nAVAIL/::AVAIL::/gp }' | sort | sed "s/::/\n/g" Jim Doe AVAIL John Doe AVAIL Sara Doe CALL 
0
source

All Articles