如何在文件末尾添加换行符?

如何在文件末尾添加换行符?

使用版本控制系统时,当 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 不会在读/写时附加换行符。

相关内容