我想这里的每个人都熟悉这句谚语,即所有文本文件都应该以换行符结尾。我已经知道这个“规则”很多年了,但我一直在想——为什么?
当前回答
这可能与以下两者之间的差异有关:
文本文件(每行应该以行尾结尾)二进制文件(没有真正的“行”可言,必须保留文件的长度)
如果每一行都以行尾结尾,这就避免了,例如,连接两个文本文件会使第一行的最后一行与第二行的第一行对齐。
此外,编辑器可以在加载时检查文件是否以行尾结尾,将其保存在本地选项“eol”中,并在写入文件时使用该选项。
几年前(2005年),许多编辑(ZDE、Eclipse、Scite…)确实“忘记”了最后的EOL,这并不是很受欢迎。不仅如此,他们还错误地将最后的EOL解释为“开始一行”,实际上开始显示另一行,就好像它已经存在一样。与在上述编辑器之一中打开文本文件相比,这在“适当”的文本文件中是非常明显的,该文件具有良好的文本编辑器(如vim)。它在文件的最后一行下面显示了一行。你会看到这样的情况:
1 first line
2 middle line
3 last line
4
其他回答
很可能只是一些解析代码希望它在那里。
我不确定我是否会认为这是一条“规则”,而且这肯定不是我虔诚地遵守的。最明智的代码将知道如何逐行解析文本(包括编码)(任何行结尾的选择),最后一行是否有换行符。
的确,如果你以一条新的线结束:EOL和EOF之间(理论上)是否有一条空的最终线?一个值得思考的。。。
最后缺少换行符的文件还有一个实际的编程问题:read-Bash内置(我不知道其他read实现)无法按预期工作:
printf $'foo\nbar' | while read line
do
echo $line
done
这只打印foo!原因是,当read遇到最后一行时,它将内容写入$line,但返回退出代码1,因为它已到达EOF。这打破了while循环,因此我们永远无法到达echo$line部分。如果要处理这种情况,必须执行以下操作:
while read line || [ -n "${line-}" ]
do
echo $line
done < <(printf $'foo\nbar')
也就是说,如果由于文件末尾的非空行导致读取失败,则执行回显。当然,在这种情况下,输出中将有一个额外的换行符,而输入中没有。
现在已经很晚了,但我在文件处理中遇到了一个错误,这是因为文件没有以空换行结尾。我们使用sed处理文本文件,sed省略了输出的最后一行,这导致无效的json结构,并将流程的其余部分发送到失败状态。
我们所做的就是:
有一个示例文件,比如:foo.txt,其中包含一些json内容。
[{
someProp: value
},
{
someProp: value
}] <-- No newline here
该文件是在寡妇计算机中创建的,窗口脚本正在使用PowerShell命令处理该文件。一切都很好。
当我们使用sed命令sed的|value|newValue|g'foo.txt>foo.txt.tmp处理同一文件时
新生成的文件是
[{
someProp: value
},
{
someProp: value
和boom,由于无效的JSON,它使其余过程失败。
因此,用空的新行结束文件始终是一个好的做法。
假设文件正在被处理,而文件仍由另一个进程生成。
可能与此有关?指示文件已准备好处理的标志。
基本上,如果没有得到最终EOL EOF,许多程序将无法正确处理文件。
GCC警告您这一点,因为它是C标准的一部分。(第5.1.1.2节明显)
“文件末尾没有换行符”编译器警告
推荐文章
- 如何在Python中获得所有直接子目录
- 即使模板文件存在,Flask也会引发TemplateNotFound错误
- 如何在Ruby中创建文件
- 如何从命令行通过mysql运行一个查询?
- 在创建守护进程时执行双fork的原因是什么?
- __FILE__宏显示完整路径
- 对以制表符分隔的文件进行排序
- 如何使用查找命令从列表中查找所有具有扩展名的文件?
- 如何将文件指针(file * fp)转换为文件描述符(int fd)?
- 如何删除文件中的特定行?
- 在Bash中获取日期(比当前时间早一天)
- Linux: kill后台任务
- 使用Java重命名文件
- 在OSX中永久设置PATH环境变量
- 如何从Python包内读取(静态)文件?