使用版本控制系统时,当 diff 说 时,我对噪音感到恼火No newline at end of file
。
所以我想知道:如何在文件末尾添加换行符以消除这些消息?
答案1
干得好:
sed -i -e '$a\' file
或者对于 OS X sed
:
sed -i '' -e '$a\' file
这会\n
在文件末尾添加仅有的如果它还没有以换行符结束。因此,如果您运行它两次,它不会添加另一个换行符:
$ cd "$(mktemp -d)"
$ printf foo > test.txt
$ sed -e '$a\' test.txt > test-with-eol.txt
$ diff test*
1c1
< foo
\ No newline at end of file
---
> foo
$ echo $?
1
$ sed -e '$a\' test-with-eol.txt > test-still-with-one-eol.txt
$ diff test-with-eol.txt test-still-with-one-eol.txt
$ echo $?
0
怎么运行的:
$
表示文件结束a\
将以下文本(在本例中没有任何内容)附加到新行上
换句话说,如果最后一行包含非换行符,则追加换行符。
答案2
为了递归地清理项目,我使用这个 oneliner:
git ls-files -z | while IFS= read -rd '' f; do if file --mime-encoding "$f" | grep -qv binary; then tail -c1 < "$f" | read -r _ || echo >> "$f"; fi; done
解释:
git ls-files -z
列出存储库中的文件。它采用可选模式作为附加参数,如果您想将操作限制到某些文件/目录,则在某些情况下该参数可能很有用。作为替代方案,您可以使用find -print0 ...
或类似的程序来列出受影响的文件 - 只需确保它发出NUL
-分隔条目。while IFS= read -rd '' f; do ... done
迭代条目,安全地处理包含空格和/或换行符的文件名。if file --mime-encoding "$f" | grep -qv binary
检查文件是否为二进制格式(例如图像)并跳过它们。tail -c1 < "$f"
从文件中读取最后一个字符。read -r _
如果缺少尾随换行符,则以非零退出状态退出。|| echo >> "$f"
如果上一个命令的退出状态非零,则在文件中追加换行符。
答案3
看一看:
$ echo -n foo > foo
$ cat foo
foo$
$ echo "" >> foo
$ cat foo
foo
所以echo "" >> noeol-file
应该做到这一点。 (或者您是想要求识别这些文件和修复它们?)
编辑删除""
了echo "" >> foo
(参见@yuyichao的评论)
编辑2再次添加""
(但请参阅@Keith Thompson 的评论)
答案4
另一种解决方案使用ed
.此解决方案仅影响最后一行,并且仅当\n
缺失时:
ed -s file <<< w
它本质上是通过脚本打开文件进行编辑,该脚本是w
将文件写回磁盘的单个命令。它是基于这句话发现的ed(1)
手册页:
局限性 (...) 如果文本(非二进制)文件不是以换行符终止的, 然后 ed 在读/写它时附加一个。在二进制的情况下 文件,ed 不会在读/写时附加换行符。