今天碰到一个很有趣的问题,就是有一个文件,我们需要得到他的行数,明明是 n
行的文本,使用 wc
命令总会少一行。
wc -l foo.txt
当时我的第一反应是 wc
命令应该和最后一行没有换行符有关,因为那个文件的内容是使用下面的代码生成的,这样的话就能解释为什么得到 n-1
这个结果了。
$filecontent = implode("\n", $arr);
man
一下 wc
的命令说明。
A line is defined as a string of characters delimited by a <newline> character. Characters beyond the final <newline> character will not be included in the line count.
的确如此,那么问题就解决了吗?当然没有,因为当时还有一个奇怪的现象,就是如果我使用 vim
编辑并保存这个文件,wc
命令的结果就恢复“正常”了。
后来我开始怀疑有不可见字符,而且这个字符是 vim
加的。我当时是这样 Google 的。
vim auto newline end of file
果然被我找到了一个回答。我们可以当场做一个实验,先使用 vim
新建一个文件,名为 foo.txt
,输入下面的文本。
a
b
再运行 wc -l foo.txt
,结果会是 2
。然后我们使用回答里的命令,重新保存文件。
vim -b foo.txt
:set noeol
:wq
再运行 wc -l foo.txt
,结果会是 1
,因为关掉了文件未尾自动加的换行。这就是为什么之前用 vim
保存过后(即使不编辑),wc
的结果还是会改变的原因。
这让我想起了以前使用 VC6.0
写 C
的时候,源文件最后如果没有多出一个空行,就会警告,提到 VC6.0
真是怀念啊,可能这就是我的青春吧,狗日的哈哈哈。
最后,这个本质其实是和 POSIX
对 newline
的定义有关的,这样所有问题都能解释了。
3.206 Line
A sequence of zero or more non- <newline> characters plus a terminating <newline> character.
晚上在全家买了一罐樱桃味的可乐,然后解决了问题,很开心 \m/