我想在文件末尾添加换行符,如果它不存在,这是为了防止文件末尾有多个换行符。
我希望使用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
如果它没有,它会添加一个换行符,但如果它存在则删除......这让我很困惑..
答案 0 :(得分:34)
GNU:
sed -i '$a\' *.txt
OS X:
sed -i '' '$a\' *.txt
$
解决了最后一行问题。 a\
是附加功能。
sed -i '' -n p *.txt
-n
禁用打印,p
打印图案空间。 p
在OS X的sed中添加了一个缺少的换行符,但在GNU sed中没有,所以这对GNU sed不起作用。
awk 1
1
可以替换为评估为true的任何内容。修改文件:
{ rm file;awk 1 >file; }<file
[[ $(tail -c1 file) && -f file ]]&&echo ''>>file
从命令替换的结果中删除尾随换行符,因此$(tail -c1 file)
仅在file
以换行符结束或为空时才为空。如果-f file
为空,则file
为false。 [[ $x ]]
相当于bash中的[[ -n $x ]]
。
答案 1 :(得分:8)
而不是处理整个文件,只需要在最后添加换行符,只需检查最后一个字符,如果不换行符,请附加一个。测试换行有点有趣,因为shell通常会从字符串末尾修剪它们,所以我附加“x”来保护它:
if [ "$(tail -c1 "$inputfile"; echo x)" != $'\nx' ]; then
echo "" >>"$inputfile"
fi
请注意,这会将换行符附加到空文件,这可能不是您想要的。如果您想单独保留空文件,请添加另一个测试:
if [ -s "$inputfile" ] && [ "$(tail -c1 "$inputfile"; echo x)" != $'\nx' ]; then
echo "" >>"$inputfile"
fi
答案 2 :(得分:6)
由于它删除了换行符,如果它不存在,你可以简单地使用:
echo "" >> file; sed -ie '/^$/d;$G' file; sed -ie '/^$/d;$G' file
添加换行符并删除所有内容然后添加换行符。不是优雅的方式,但肯定有效:)
答案 3 :(得分:2)
使用awk:
awk '/^$/{f=1}END{ if (!f) {print "\r"}}1' inputfile
匹配空行^$
(就像你一样)并设置一个标志。如果未在末尾设置标记,请放置换行符。
注意:\r
在OS X中。将\n
用于其他。
答案 4 :(得分:1)
read
获取文件的最后一个字符将其管道输入read
,如果在换行符之前遇到EOF,则会以非零退出代码退出(因此,如果文件的最后一个字符不是换行符)。如果echo
退出非零,则使用read
将新行添加到文件中(如果||
退出0,则满足echo
,因此var array = [];
for ( var row = 0; row < tablerows; ++row ) {
var tablerow = element.getRow(row)
array[row] = [];
for ( var cell=0; cell < tablerow.getNumCells(); ++cell) {
var celltext = tablerow.getChild(cell).getText();
array[row][cell] = celltext;
}
}
Logger.log(JSON.stringify(array)); // debug
命令不是不跑。
来自http://backreference.org/2010/05/23/sanitizing-files-with-no-trailing-newline/。
答案 5 :(得分:0)
我使用带有dos2unix
标记的--newline
(或对应方)来解决此任务。优点是这些工具可以自己检测二进制文件。我喜欢tail -c1
的解决方案,但事先过滤二进制文件对我来说真的很慢。
dos2unix --newline my_file.txt
最后我编写了一个搜索我的项目目录的脚本,将所有文件转换为LF
(dos2unix
)除了*.cmd
个文件(CRLF
,unix2dos
)并使用该标志通过一次调用获得新行。
答案 6 :(得分:0)
尝试使用vi
或ex
:
ex -scwq foo.txt
或多个文件:
vi -es +"bufdo wq" *.txt
ex -s +"bufdo wq" *.txt
如果缺少文件保存,会自动在EOF处添加EOL。
要递归申请某些文件,请使用a new globbing option(**
),例如**/*.txt
(shopt -s globstar
启用)。
答案 7 :(得分:0)
仅使用Bash
您可以使用“命令替换”(删除尾随的换行符)和“这里的字符串”(附加换行符):
Command Substitution
Command substitution allows the output of a command to replace the command name. There are two
forms:
$(command)
or
`command`
Bash performs the expansion by executing command in a subshell environment and replacing the com-
mand substitution with the standard output of the command, with any trailing newlines deleted.
Embedded newlines are not deleted, but they may be removed during word splitting. The command sub-
stitution $(cat file) can be replaced by the equivalent but faster $(< file).
Here Strings
A variant of here documents, the format is:
[n]<<<word
The word undergoes brace expansion, tilde expansion, parameter and variable expansion, command sub-
stitution, arithmetic expansion, and quote removal. Pathname expansion and word splitting are not
performed. The result is supplied as a single string, with a newline appended, to the command on
its standard input (or file descriptor n if n is specified).
这是它的工作方式:
cat <<<"$(<inputfile)"
输出到文件:
cat <<<"$(<inputfile)" >outputfile
如果您需要inputfile
和outputfile
是相同的文件名,则有两个选择-使用sponge
命令,通过更多命令替换保存到临时变量,或保存到临时文件。
使用Sed
其他人建议使用
sed '$a\' inputfile
,不将任何内容追加到最后一行。很好,但我认为
sed '$q' inputfile
更加清晰,因为它在最后一行退出。或者你可以做
sed -n 'p'
使用-n
抑制输出,但使用p
打印回去。
在以上任何一种情况下,sed
都将修复该行并添加换行符,至少对于GNU和BSD sed而言。但是,我不确定此功能是否由POSIX定义。 sed
的一个版本可能会跳过您的行而没有换行符,因为行定义为
A sequence of zero or more non- characters plus a terminating character.