wc 命令读取文件行数时出错

wc 命令读取文件行数时出错

我一直wc -l在检查文件中存在的行数。它一直工作得很好,但这次不行。

我有 120 个大文件,每个文件应该至少有两行。我刚刚对这些文件进行了一些文本编辑工作,以删除和添加新行。我试图wc -l *像往常一样使用来检查最终的行数。输出显示大多数文件只有一行。

我打开了其中一个文件(从命令结果显示它只有一行),vim我可以看到它正好有 2 行。退出vim并使用 再次检查wc -l,该文件的行数显示为 2。

有人知道这里发生了什么吗?我怎样才能解决这个问题而不是用打开所有 120 个文件vim

PS:我的文件的最后一行不是空的。

答案1

常见的 gnu 实现wc

'wc' 计算每个给定 FILE 中的字节数、字符数、空格分隔的单词数
和换行符数,如果没有给出或 FILE 为 '-',则计算标准输入数。

因此,如果文件中没有最后的换行符,则输出的“行”部分wc将比预期少 1。例如下面将输出 1

printf 'hello\nworld' | wc -l 

OP 在评论中确认 vim 正在报告缺少最终换行符。如果已知所有文件都存在此问题,一个简单的修复方法是

 for f in *
 do
     echo >> "$f"
 done

向每个文件附加换行符。

如果所有文件缺少换行符,有条件地在其末尾添加换行符的一种方法是使用 sed。

sed -s -i '$s/$/\n/;P;d' *

使用一些 GNU 扩展,-s分别处理每个文件,-i进行就地编辑,并允许\n表示换行符。 sed 程序本身表示在每个文件的最后一行附加一个换行符,并为每一行打印到第一个换行符并移至下一行。

答案2

这并不完全是一个答案,而是分享一个我经常使用的微型个人工具来标准化文本文件(txtnorm):

#!/usr/bin/perl -spi
our($s);
s/\n\r|\r\n|\n|\r/\n/g;                 ## normalize \n
s/^(\xFF\xFE|\xFE\xFF|\xEF\xBB\xBF)//;  ## remove BOM !
s/(?<=.)\z/\n/;                         ## ensure newline at eof

if($s){ s/\xC2\xA0/ /g }                ## -s non breaking spaces-> " "

txtnorm *.txt标准化行尾,确保 eof 处换行,删除 BOM 并(使用 -s)可以标准化不间断空格。

请务必仅在文本文件上使用它。

相关内容