按行长度(包括空格)对文本文件进行排序

2024-08-21 08:41:37 浏览数 (1)

问题

我有一个类似这样的CSV文件

代码语言:javascript复制
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

我需要按包括空格在内的行长度排序。下面的命令不包括空格,有没有办法修改它,使它为我工作?

代码语言:javascript复制
cat textfile | awk '{ print length, $0 }' | sort -n | awk '{$1=""; print $0}'

回答

可以使用如下命令:

代码语言:javascript复制
awk '{ print length, $0 }' textfile | sort -n | cut -d" " -f2-

{ print length, $0 }: 是一个简单的 awk 脚本,它对文件的每一行执行以下操作:

  • length: 返回当前行的字符数(包括空格和换行符)。
  • $0: 表示整个当前行的内容。

sort 命令,用于对输入进行排序。

  • -n: 指定按照数值顺序进行排序,这里是指按行长度排序。

cut 命令,用于从每行中选择或删除字段。

  • -d" ": 设置字段分隔符为空格。
  • -f2-: 指定从第二个字段开始输出所有字段。

结合前面两步的结果,cut -d" " -f2- 将移除每行的第一个字段(即行长度),保留后面的字段(即原始的行内容)。

为什么提问者的尝试解决方案会失败?

有趣的是,我们可以注意到两者之间的差异:

代码语言:javascript复制
echo "hello   awk   world" | awk '{print $0}'
echo "hello   awk   world" | awk '{$1="hello"; print $0}'

它们各自输出:

代码语言:javascript复制
hello   awk   world
hello awk world

(gawk 的)手册中只是顺便提到,当你更改一个字段时,awk 将会根据分隔符等重新构建整个 $0。我猜这不是疯狂的行为。其中写道:

“最后,有时候为了方便起见,需要强制让 awk 根据当前字段的值和输出字段分隔符(OFS) 重新构建整个记录。要做到这一点,可以使用看似无害的赋值操作:”

代码语言:javascript复制
 $1 = $1   # force record to be reconstituted
 print $0  # or whatever else with $0

“这迫使 awk 重建记录。”


参考

  • stackoverflow question 5917576
  • man awk
  • man cut

0 人点赞