查找任何超过特定长度的行

row*_*ran 62 text-processing

是否可以在文件中找到超过 79 个字符的任何行?

man*_*ork 107

根据我的测试,按照降低速度的顺序(在 UTF-8 语言环境和 ASCII 输入的 GNU 系统上):

grep '.\{80\}' file

perl -nle 'print if length$_>79' file

awk 'length>79' file

sed -n '/.\{80\}/p' file
Run Code Online (Sandbox Code Playgroud)

除了perl¹一个(或awk/ grep/sed实现(像mawk或busybox的),其不支持多字节字符),该计数的数量而言的长度字符(根据LC_CTYPE语言环境的设置),而不是字节

如果输入中的字节不构成有效字符的一部分(有时会在语言环境的字符集为 UTF-8 且输入采用不同编码时发生),则根据解决方案和工具实现,这些字节要么算作 1 个字符,要么算作 0 或不匹配.

例如,包含 30 asa 0x80 字节、30 bs、0x81 字节和 30 UTF-8 és(编码为 0xc3 0xa9)的行,在 UTF-8 语言环境中将.\{80\}与 GNU grep/不匹配sed(因为独立的 0x80 字节不匹配.),长度为 30+1+30+1+2*30=122 with perlor mawk,3*30=90 with gawk.

如果你想以字节为单位来算,固定区域设置C使用LC_ALL=C grep/awk/sed...

这将使所有 4 个解决方案都认为上面的行包含 122 个字符。除了 inperl和 GNU 工具之外,对于包含 NUL 字符(0x0 字节)的行,您仍然会有潜在的问题。


¹perl行为可能会受到PERL_UNICODE环境变量的影响

  • 顺便说一句,如果你用 `^` 将正则表达式锚定到行的开头,它会稍微快一点:例如 `grep '^.\{80\}' file`。 (10认同)
  • 足够大的 N 值使用 grep 失败,但使用 awk 成功。(例如,`grep '^.\{1000\}' file` 返回 `grep: invalid repeat count(s)`,而 `awk 'length>1000' file` 成功。) (7认同)
  • 与所有其他解决方案不同,perl 解决方案不考虑可变大小编码,例如 UTF-8。 (5认同)