Tristan Lanford
Tristan Lanford

Reputation: 93

How to sort with multiple lines in bash?

I am trying to sort a list of names followed by another string such as:

John Doe
AVAIL

Sara Doe
CALL

Jim Doe
AVAIL

I am trying to sort these by name but can't seem to figure it out with sort. Can someone provide some guidance?

My final output would look like this:

Jim Doe
AVAIL

John Doe
AVAIL

Sara Doe
CALL

Much appreciated!

Upvotes: 9

Views: 6113

Answers (3)

johnshen64
johnshen64

Reputation: 3884

not directly, but you can use some intermediate form like this. i am assuming that your value (CALL, AVAIL, etc.) is limited. otherwise you need to use patterns that are more complicated, but it can be done. actually anything 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::/g p }' | sort | sed "s/::/\n/g"
Jim Doe
AVAIL

John Doe
AVAIL

Sara Doe
CALL

Upvotes: 0

Alex Gitelman
Alex Gitelman

Reputation: 24722

Not sure if it's going to work for you but with some limitations here is a line that kind of doing 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 blank lines in between records, name is always less than 30 characters and there is no : used in text.

I am sure you can figure how to change it if assumptions are different.

In a nutshell it, merges two lines using ':' as separator, pads first line to 30 characters and sorts using first 30 characters. Then it breaks lines back.

Upvotes: 0

Lev Levitsky
Lev Levitsky

Reputation: 65791

Probably far from optimal, but

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

seems to do the job (names is the file with records). This allows records of arbitrary length, not just 2 lines.

Upvotes: 10

Related Questions