我想这里的每个人都熟悉这句谚语,即所有文本文件都应该以换行符结尾。我已经知道这个“规则”很多年了,但我一直在想——为什么?
当前回答
一个单独的用例:当文本文件受版本控制时,提交卫生。
如果将内容添加到文件末尾,则先前是最后一行的行将被编辑为包含换行符。这意味着,打开文件以了解该行最后一次编辑的时间将显示换行符添加,而不是您实际希望看到的提交。
(该示例特定于git,但同样的方法也适用于其他版本控制系统。)
其他回答
这个答案是一个技术性的答案,而不是观点。
如果我们想成为POSIX纯粹主义者,我们将一行定义为:
一个由零个或多个非<换行符>字符加上一个终止<换行符]字符组成的序列。
资料来源:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206
不完整的行,如:
文件末尾的一个或多个非<换行符>字符序列。
资料来源:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_195
文本文件为:
包含组织成零行或多行的字符的文件。这些行不包含NUL字符,长度不能超过{LINE_MAX}字节,包括<换行符>字符。虽然POSIX.1-2008没有区分文本文件和二进制文件(参见ISO C标准),但许多实用程序在操作文本文件时只产生可预测或有意义的输出。具有此类限制的标准实用程序总是在其STDIN或INPUT files部分中指定“文本文件”。
资料来源:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_397
字符串为:
一个连续的字节序列,以第一个空字节结尾并包括第一个空字符。
资料来源:https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_396
由此,我们可以得出,只有当我们处理文件的一行或文件作为文本文件的概念时,我们才可能遇到任何类型的问题(即文本文件是由零行或多行组成的组织,并且我们知道的行必须以<newline>结尾)。
大小写:wc-l文件名。
从wc手册中,我们了解到:
行定义为一个由<newline>字符分隔的字符串。
如果JavaScript、HTML和CSS文件是文本文件,那么它们的含义是什么?
在浏览器、现代IDE和其他前端应用程序中,在EOF时跳过EOL没有问题。应用程序将正确解析文件。由于并非所有操作系统都符合POSIX标准,因此非OS工具(例如浏览器)根据POSIX标准(或任何OS级标准)处理文件是不切实际的。
因此,我们可以相对确信,EOF的EOL在应用程序级别几乎不会产生负面影响——无论它是否在UNIX OS上运行。
此时,我们可以自信地说,在客户端处理JS、HTML和CSS时,在EOF中跳过EOL是安全的。实际上,我们可以声明,缩小其中任何一个不包含<newline>的文件都是安全的。
我们可以进一步说,就NodeJS而言,它也不能遵守POSIX标准,因为它可以在非POSIX兼容的环境中运行。
那我们还剩什么?系统级工具。
这意味着唯一可能出现的问题是那些努力使其功能符合POSIX语义的工具(例如wc中所示的行的定义)。
即使如此,并不是所有的shell都会自动遵守POSIX。例如,Bash不默认为POSIX行为。有一个开关可以启用它:POSIXLY_CORRECT。
EOL的价值值得思考:https://www.rfc-editor.org/old/EOLstory.txt
为了所有实际意图和目的,让我们继续走在工具轨道上,考虑一下:
让我们处理一个没有EOL的文件。至此,本例中的文件是一个缩小的JavaScript,没有EOL。
curl http://cdnjs.cloudflare.com/ajax/libs/AniJS/0.5.0/anijs-min.js -o x.js
curl http://cdnjs.cloudflare.com/ajax/libs/AniJS/0.5.0/anijs-min.js -o y.js
$ cat x.js y.js > z.js
-rw-r--r-- 1 milanadamovsky 7905 Aug 14 23:17 x.js
-rw-r--r-- 1 milanadamovsky 7905 Aug 14 23:17 y.js
-rw-r--r-- 1 milanadamovsky 15810 Aug 14 23:18 z.js
请注意,cat文件大小正好是其各个部分的总和。如果JavaScript文件的连接是JS文件的一个问题,那么更合适的问题是用分号开始每个JavaScript文件。
正如其他人在本主题中提到的:如果你想抓取两个输出仅为一行而不是两行的文件,该怎么办?换句话说,猫做它应该做的事。
猫的男人只提到阅读输入到EOF,而不是<newline>。请注意,cat的-n开关还将打印出一个非<换行符>终止的行(或不完整的行)作为一行,即计数从1开始(根据man的说法)
-n对输出线进行编号,从1开始。
现在我们了解了POSIX是如何定义行的,这种行为变得模棱两可,或者说实际上是不合规的。
了解给定工具的用途和合规性将有助于确定使用EOL结束文件的重要性。在C、C++、Java(JARs)等中,一些标准会规定一个新的有效性标准——JS、HTML、CSS不存在这样的标准。
例如,可以不使用wc-l文件名,而是使用awk“{x++}END{print x}”文件名,并确保任务的成功不会受到我们可能要处理的文件(例如,第三方库,例如我们固化的精简JS)的影响,除非我们的目的是真正按照POSIX兼容的方式计算行数。
结论
在现实生活中,对于某些文本文件(如JS、HTML和CSS),在EOF时跳过EOL会产生负面影响(如果有的话)。如果我们依赖于<newline>的存在,我们将工具的可靠性限制在我们编写的文件上,并将自己暴露在第三方文件引入的潜在错误中。
故事的寓意:工程师工具没有依赖EOF中EOL的弱点。
请随意发布用例,因为它们适用于JS、HTML和CSS,我们可以在其中检查跳过EOL是如何产生不利影响的。
有些工具会这样做。例如,wc期望如下:
$ echo -n "Line not ending in a new line" | wc -l
0
$ echo "Line ending with a new line" | wc -l
1
基本上,如果没有得到最终EOL EOF,许多程序将无法正确处理文件。
GCC警告您这一点,因为它是C标准的一部分。(第5.1.1.2节明显)
“文件末尾没有换行符”编译器警告
我个人喜欢源代码文件末尾的新行。
它可能起源于Linux或所有UNIX系统。我记得有编译错误(如果我没弄错的话是gcc),因为源代码文件没有以空的新行结尾。为什么会这样呢。
很可能只是一些解析代码希望它在那里。
我不确定我是否会认为这是一条“规则”,而且这肯定不是我虔诚地遵守的。最明智的代码将知道如何逐行解析文本(包括编码)(任何行结尾的选择),最后一行是否有换行符。
的确,如果你以一条新的线结束:EOL和EOF之间(理论上)是否有一条空的最终线?一个值得思考的。。。
推荐文章
- 如何生成一个核心转储在Linux上的分段错误?
- 在Python中如何在Linux和Windows中使用“/”(目录分隔符)?
- 使用sh shell比较字符串
- 从包含文件名的路径获取不包含文件名的完整路径
- Visual Studio代码-在文件末尾插入换行符
- 只列出UNIX中的目录
- Git:从另一个分支复制目录中的所有文件
- PHP,获取没有文件扩展名的文件名
- 如何限制从grep返回的结果的数量?
- 如何管道列表的文件返回的找到命令到猫查看所有文件
- 以相对于当前目录的路径递归地在Linux CLI中列出文件
- 如何使用xargs复制名称中有空格和引号的文件?
- 如何在远程系统上使用Ansible任务移动/重命名文件
- 在makefile中抑制命令调用的回声?
- Shell脚本for循环语法