我只想在文件末尾添加一个不存在的换行符。这是为了防止在文件末尾出现多个换行符。
我希望使用sed
。以下是我当前代码遇到的问题:
sed -i -e '/^$/d;$G' /inputfile
echo file1
name1
name2
echo file2
name3
name4
(newline)
当我在文件上运行代码时
echo file1
name1
name2
(newline)
echo file2
name3
name4
如果没有换行符,它会添加一个换行符;如果存在换行符,它会删除换行符......这让我很困惑。
9条答案
按热度按时间yhuiod9q1#
已删除
GNU的:
OS X操作系统:
$
寻址最后一行。a\
是附加函数。OS X的sed
-n
禁用打印,p
打印模式空间。p
在OS X的sed中添加了一个缺少的换行符,但在GNU sed中没有,因此这在GNU sed中不起作用。awk的名称
1
(数字1)可以替换为计算结果为true的任何值。就地修改文件:狂欢
将从命令替换的结果中删除尾随换行符,因此只有当
file
以换行符结尾或为空时,$(tail -c1 file)
才为空。如果file
为空,则-f file
为false。[[ $x ]]
等效于bash中的[[ -n $x ]]
。lztngnrs2#
不是用see处理整个文件,只是在结尾处添加一个换行符,而是检查最后一个字符,如果它 * 不是 * 换行符,就追加一个。测试换行符有点意思,因为shell通常会从字符串结尾处删除它们,所以我追加“x”来保护它:
请注意,这会在空文件后追加换行符,这可能不是您想要的。如果您不想处理空文件,请添加另一个测试:
0yg35tkg3#
由于它会删除不存在的换行符,因此您可以简单地用途:
添加一个新行并删除所有内容,然后添加新行。不是优雅的方式,但肯定有效:)
zrfyljdw4#
获取文件的最后一个字符,将其管道化到
read
中,如果在换行符前遇到EOF,则read
将以非零退出代码退出如果read
以非零值存在,则使用echo
在文件上追加一个换行符(如果read
退出0,说明满足||
,所以echo
命令不运行)。从http://backreference.org/2010/05/23/sanitizing-files-with-no-trailing-newline/开始。
csga3l585#
使用awk:
匹配空行
^$
(就像你做的那样)并设置一个标志。如果末尾没有设置标志,则放置换行符。注:
\r
在OS X中。其他请使用\n
。ugmeyewa6#
尝试使用
vi
或ex
:或用于多个文件:
它会在文件保存时在EOF处自动添加EOL。
要递归应用某些文件,请使用a new globbing option(
**
),例如**/*.txt
(通过shopt -s globstar
启用)。xmjla07d7#
仅使用Bash
您可以将命令替换(删除尾随换行符)与Here String(附加换行符)一起使用:
以下是它的工作原理:
输出到文件:
如果您需要
inputfile
和outputfile
具有相同的文件名,您有两个选项-使用sponge
命令、保存到带有更多命令替换的临时变量或保存到临时文件。使用Sed
其他人建议使用
它不会在最后一行附加任何内容。这很好,但我认为
因为它在最后一行退出。或者您可以
它使用
-n
来抑制输出,但使用p
将其打印出来。在任何一种情况下,
sed
都将修复行并添加一个换行符,至少对于GNU和BSD sed是这样。但是,我不确定POSIX是否定义了此功能。sed
的一个版本可能会跳过您的行而不添加换行符,因为行定义为由零个或多个非字符加上一个终止字符组成的序列。
iqjalb3h8#
我使用
dos2unix
(或对应的--newline
)和--newline
标志解决了这个问题。优点是这些工具可以自己检测二进制文件。我喜欢使用tail -c1
的解决方案,但是预先过滤二进制文件对我来说 * 真的 * 很慢。最后,我编写了一个脚本,搜索我的项目目录,将除了
*.cmd
文件(CRLF
,unix2dos
)之外的所有文件转换为LF
(dos2unix
),并使用标志通过一次调用获得正确的换行符。jogvjijk9#
使用标准shell命令有一个很好的解决方案:
tail
输出文件最后一个字节read
将一行读入变量。如果没有指定变量,则不执行任何操作,但如果在换行符之前出现EOF,则以代码1退出。echo
仅在读取失败时运行(即,如果最后一个字符不是换行符),并在file.txt
后追加一个换行符