POSIXwc
命令计算文件中的 POSIX 行数。 POSIX 标准定义了一个线作为带有后缀 的文本字符串\n
。如果没有\n
,纯文本字符串就不能称为行。
但对我来说,计算文件中有多少行文本字符串更自然。有没有简单的方法可以做到这一点?
root:[~]# printf "aa\nbb" | wc -l
1
root:[~]# printf "aa\nbb\n" | wc -l
2
root:[~]#
答案1
使用 GNU sed
,您可以使用:
sed '$=;d'
因为 GNUsed
确实将最后一个换行符之后的那些额外字符视为额外行。与大多数 GNU 实用程序一样, GNUsed
也支持输入中的 NUL 字符,并且对行长度没有限制(根据 POSIX,这两个条件使输入成为非文本)。
POSIXly,建立在@Inian的回答支持过长的行和 NUL 字节:
LC_ALL=C tr -cs '\n' '[x*]' | awk 'END {print NR}'
那tr
命令将除换行符之外的一个或多个字符的所有序列(每个字节解释为 C 语言环境中的字符以避免解码问题)转换为一 x
字符,因此awk
输入记录的长度将为 0 或 1 个字节,并且其输入仅包含x
和 换行符。
$ printf '%10000s\na\0b\nc\nd' | wc -l
3
$ printf '%10000s\na\0b\nc\nd' | mawk 'END{print NR}'
2
$ printf '%10000s\na\0b\nc\nd' | busybox awk 'END{print NR}'
5
$ printf '%10000s\na\0b\nc\nd' | gawk 'END{print NR}'
4
$ printf '%10000s\na\0b\nc\nd' | LC_ALL=C tr -cs '\n' '[x*]' | mawk 'END{print NR}'
4
答案2
您可以使用awk
它,它有一个特殊变量NR
,该变量跟踪从文件开头开始的当前记录数。该变量在每行末尾递增。当在块上打印时END
,即在处理所有输入行之后,它会打印最后处理的记录的编号。
printf "aa\nbb" | awk 'END { print NR }'
2
printf "aa\nbb\n" | awk 'END { print NR }'
2