2012-07-03 44 views
7

我试图理清名字,然后另一个字符串如列表:如何在bash中对多行进行排序?

John Doe 
AVAIL 

Sara Doe 
CALL 

Jim Doe 
AVAIL 

我试图以按名称排序这些,但似乎无法与排序弄明白。有人可以提供一些指导吗?

我最后的输出应该是这样的:

Jim Doe 
AVAIL 

John Doe 
AVAIL 

Sara Doe 
CALL 

非常感谢!

+0

有趣的是,你的榜样,它不清楚你是否排序相对于第一或第二线;) –

+0

对不起我真的想按字母顺序排序为第一行。 –

回答

6

从最佳可能远,但

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

似乎做的工作(names是记录文件)。这允许任意长度的记录,而不仅仅是2行。

+0

它绝对适合我的目的。 –

+1

@lev对于那些在“sed”中不太“流利”的人,你能否简短地叙述表达式的第一部分?你的基本方法是消除换行符(把'\ v'放在它的位置),排序一长串,然后替换'\ n'的'\ v'? – Levon

+0

@Levon你是完全正确:)它读一切都交给一个空行(一个记录),然后改变它换行到'\ v'。现在所有记录都在单行上。他们被排序,然后'\ v'被转换回'\ n'。 –

0

不知道它会为你但这里有一些限制的工作是你需要那种做一个什么样的线。

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

假设:有在记录之间不空行,名字总是小于30个字符并没有在文本中使用:

我相信你能弄清楚如何改变它,如果假设是不同的。

简而言之它,合并使用两个线“:”作为分隔符,焊盘第一行30个字符和各种使用前30个字符。然后它打破了线路。

0

不是直接的,但你可以使用一些中间形式是这样的。我假设你的价值(CALL,AVAIL等)是有限的。否则你需要使用更复杂的模式,但它可以完成。其实任何事情都有可能在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 
相关问题