小编典典

按行长对文本文件进行排序,包括空格

all

我有一个看起来像这样的 CSV 文件

AS2345,ASDF1232, Mr. Plain Example, 110 Binary ave.,Atlantis,RI,12345,(999)123-5555,1.56
AS2345,ASDF1232, Mrs. Plain Example, 1121110 Ternary st. 110 Binary ave..,Atlantis,RI,12345,(999)123-5555,1.56
AS2345,ASDF1232, Mr. Plain Example, 110 Binary ave.,Liberty City,RI,12345,(999)123-5555,1.56
AS2345,ASDF1232, Mr. Plain Example, 110 Ternary ave.,Some City,RI,12345,(999)123-5555,1.56

我需要按行长(包括空格)对其进行排序。以下命令不包含空格,有没有办法修改它以便对我有用?

cat $@ | awk '{ print length, $0 }' | sort -n | awk '{$1=""; print $0}'

阅读 119

收藏
2022-08-02

共1个答案

小编典典

回答

cat testfile | awk '{ print length, $0 }' | sort -n -s | cut -d" " -f2-

或者,对任何等长的行进行原始(可能是无意的)子排序:

cat testfile | awk '{ print length, $0 }' | sort -n | cut -d" " -f2-

在这两种情况下,我们已经解决了您提出的问题,不再使用 awk 进行最终剪辑。

匹配长度的线 - 在平局的情况下该怎么做:

该问题没有说明是否需要对匹配长度的行进行进一步排序。我假设这是不需要的,并建议使用-s( --stable)
来防止这些行相互排序,并保持它们在输入中出现的相对顺序。

(那些想要更好地控制这些关系排序的人可能会查看 sort 的--key选项。)

为什么问题的尝试解决方案失败(awk line-rebuilding):

有趣的是注意以下之间的区别:

echo "hello   awk   world" | awk '{print}'
echo "hello   awk   world" | awk '{$1="hello"; print}'

它们分别产生

hello   awk   world
hello awk world

(gawk’s) 手册的相关部分仅提到,当您更改一个字段时,awk 将重建整个 $0(基于分隔符等)。我想这不是疯狂的行为。它有这个:

“最后,有时可以方便地强制 awk 使用字段和 OFS 的当前值重建整个记录。为此,请使用看似无害的赋值:”

 $1 = $1   # force record to be reconstituted
 print $0  # or whatever else with $0

“这迫使 awk 重建记录。”

测试输入,包括一些等长的行:

aa A line   with     MORE    spaces
bb The very longest line in the file
ccb
9   dd equal len.  Orig pos = 1
500 dd equal len.  Orig pos = 2
ccz
cca
ee A line with  some       spaces
1   dd equal len.  Orig pos = 3
ff
5   dd equal len.  Orig pos = 4
g
2022-08-02