假设我收到了各种文件,其中一些文件的行结尾为\r
,\n
和\r\n
。当我事先不知道会发生什么时,如何有效地计算文件中的行数?
wc -l
如果有 Mac 行结尾,显然是行不通的。
Grep 在使用时显得非常不准确:
grep -o '\r' /path/to/file.txt | wc -l
给出了 1041 行,但实际上只有 299 行,并且nano
可以通过从 Mac 格式自动转换来确认这一点。
它也没有提供我所希望的多功能性,因为grep -o '[\r\n]+' /path/to/file.txt | wc -l
返回计数为 0。
我该如何正确地做到这一点?
答案1
您的grep
命令给出了太多匹配项,因为grep
使用基本正则表达式,它没有赋予特殊含义\r
——它计算的是字母“r”的出现次数。
tr
做识别\n
和\r
,这样它就可以找到所有匹配项,并让wc -c
它们逐字节计数:
tr -d -c '\n\r' < file.txt | wc -c
但由于您的文件还可能包含 Windows/DOS 行结束符 ( \r\n
),因此这些行结束符会被计算两次。您将需要一个额外的步骤将任何 DOS 样式的行结束符转换为其他形式之一,然后像以前一样计算各个行结束符:
sed 's/\r$//' file.txt | tr -d -c '\n\r' | wc -c
不幸的是,也不sed
总是能够识别\r
。您可能需要使用其他方式来指定回车符,例如 shell 自己的转义、命令echo
或将 sed 脚本放入文件中。
答案2
gawk 'END {print NR}' RS='\r|\n|\r\n' file.txt
该RS
变量指定什么被视为换行符gawk
,在本例中是正则表达式。