我正在尝试对一个包含名字和其他字符串的列表进行排序,例如:
John Doe
AVAIL
Sara Doe
CALL
Jim Doe
AVAIL
我正在尝试按名称对它们进行排序,但是使用sort似乎无法弄清楚。是否有人可以提供一些指导?
我的最终输出应该如下所示:
Jim Doe
AVAIL
John Doe
AVAIL
Sara Doe
CALL
非常感谢!
我正在尝试对一个包含名字和其他字符串的列表进行排序,例如:
John Doe
AVAIL
Sara Doe
CALL
Jim Doe
AVAIL
我正在尝试按名称对它们进行排序,但是使用sort似乎无法弄清楚。是否有人可以提供一些指导?
我的最终输出应该如下所示:
Jim Doe
AVAIL
John Doe
AVAIL
Sara Doe
CALL
可能远非最佳,但是
sed -r ':r;/(^|\n)$/!{$!{N;br}};s/\n/\v/g' names | sort | sed 's/\v/\n/g'
看起来可以完成任务(names
是记录文件)。这允许任意长度的记录,而不仅仅是2行。
sed
的人,你能简要叙述一下表达式的前半部分吗?你的基本方法是消除换行符(将 \v
放在其位置),对长行进行排序,然后用 \n
替换 \v
吗? - Levon\v
。现在所有记录都在单行上。它们被排序,然后\v
被转换回\n
。 - Lev Levitsky\v
,然后将 ---
改为换行符,然后排序,再将\v
改为\n
。 - Lev Levitsky虽然不能直接实现,但你可以使用一些中间形式来达到目的。我假设你的值(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
不确定它是否适用于您,但有一些限制,这是一行代码,可以实现您需要的功能。
awk '{if ((NR%2-1)==0) {line=sprintf("%-30s",$0)} else {print line ":" $0}}' | \
sort --key=1,30 | tr ':' '\n'
假设:记录之间没有空行,名称始终少于30个字符,并且文本中没有使用:
。
如果假设不同,我相信你可以想出如何进行更改。
简而言之,它使用“:”作为分隔符合并两行,将第一行填充到30个字符并使用前30个字符进行排序。然后再将行拆分回来。