Linux 仅当它不存在时才添加换行符
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10082204/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Add a newline only if it doesn't exist
提问by AlwynIsPat
I want to add a newline at the end of a file only if it doesn't exists, this is to prevent multiple newlines at the end of the file.
我想仅在文件不存在时在文件末尾添加换行符,这是为了防止文件末尾出现多个换行符。
I'm hoping to use sed. Here's the issues i'm having with my current code:
我希望使用 sed。这是我当前代码的问题:
sed -i -e '/^$/d;$G' /inputfile
echo file1
name1
name2
echo file2
name3
name4
(newline)
when i run my code on to the files;
当我将代码运行到文件上时;
echo file1
name1
name2
(newline)
echo file2
name3
name4
it adds a newline if it doesnt have but removes if it exists... this puzzles me..
如果它没有,它会添加一个换行符,但如果它存在则删除......这让我感到困惑..
采纳答案by P.P
Since it removes newline if it's not there, you could simply use:
由于它在不存在时删除换行符,因此您可以简单地使用:
echo "" >> file; sed -ie '/^$/d;$G' file; sed -ie '/^$/d;$G' file
Adds a newline and removes everything then adds newline. Not the elegant way, but certainly works :)
添加换行符并删除所有内容,然后添加换行符。不是优雅的方式,但肯定有效:)
回答by Gordon Davisson
Rather than processing the whole file with see just to add a newline at the end, just check the last character and if it's nota newline, append one. Testing for newline is slightly interesting, since the shell will generally trim them from the end of strings, so I append "x" to protect it:
而不是使用 see 处理整个文件以在末尾添加换行符,只需检查最后一个字符,如果它不是换行符,则附加一个。测试换行符有点有趣,因为 shell 通常会从字符串的末尾修剪它们,所以我附加 "x" 来保护它:
if [ "$(tail -c1 "$inputfile"; echo x)" != $'\nx' ]; then
echo "" >>"$inputfile"
fi
Note that this will append newline to empty files, which might not be what you want. If you want to leave empty files alone, add another test:
请注意,这会将换行符附加到空文件中,这可能不是您想要的。如果您想单独留下空文件,请添加另一个测试:
if [ -s "$inputfile" ] && [ "$(tail -c1 "$inputfile"; echo x)" != $'\nx' ]; then
echo "" >>"$inputfile"
fi
回答by ring bearer
Using awk :
使用 awk :
awk '/^$/{f=1}END{ if (!f) {print "\r"}}1' inputfile
Match blank line ^$
(just like you did) and set up a flag. If flag is not set at the end, place newline character.
匹配空行^$
(就像你做的那样)并设置一个标志。如果最后未设置标志,则放置换行符。
Note: that \r
is in OS X. Use \n
for other.
注意:这\r
是在 OS X 中。\n
用于其他。
回答by Lri
sed
sed
GNU:
GNU:
sed -i '$a\' *.txt
OS X:
操作系统:
sed -i '' '$a\' *.txt
$
addresses the last line. a\
is the append function.
$
地址最后一行。a\
是追加函数。
OS X's sed
OS X 的 sed
sed -i '' -n p *.txt
-n
disables printing and p
prints the pattern space. p
adds a missing newline in OS X's sed but not in GNU sed, so this doesn't work with GNU sed.
-n
禁用打印并p
打印模式空间。p
在 OS X 的 sed 中添加了一个缺少的换行符,但在 GNU sed 中没有,所以这不适用于 GNU sed。
awk
awk
awk 1
1
can be replaced with anything that evaluates to true. Modifying a file in place:
1
可以用任何评估为真的东西替换。就地修改文件:
{ rm file;awk 1 >file; }<file
bash
猛击
[[ $(tail -c1 file) && -f file ]]&&echo ''>>file
Trailing newlines are removed from the result of the command substitution, so $(tail -c1 file)
is empty only if file
ends with a linefeed or is empty. -f file
is false if file
is empty. [[ $x ]]
is equivalent to [[ -n $x ]]
in bash.
从命令替换的结果中删除尾随换行符,因此$(tail -c1 file)
仅当file
以换行符结尾或为空时才为空。-f file
如果file
为空则为假。[[ $x ]]
相当于[[ -n $x ]]
在 bash 中。
回答by Daniel B?hmer
I solved this task by using dos2unix
(or counterparts) with the --newline
flag. The advantage is that these tools detect binary files on their own. I like the solution with tail -c1
but filtering binary files beforehand has been reallyslow for me.
我通过使用dos2unix
(或对应的)--newline
标志解决了这个任务。优点是这些工具可以自行检测二进制文件。我喜欢这个解决方案,tail -c1
但预先过滤二进制文件对我来说真的很慢。
dos2unix --newline my_file.txt
Eventually I wrote a script that searched my project directory, converted all files to LF
(dos2unix
) except *.cmd
files (CRLF
, unix2dos
) and used the flag to get the newlines right with one call.
最终,我编写了一个脚本来搜索我的项目目录,将所有文件转换为LF
( dos2unix
) 除了*.cmd
文件 ( CRLF
, unix2dos
) 并使用该标志通过一次调用获得正确的换行符。
回答by kenorb
Try using vi
or ex
:
尝试使用vi
或ex
:
ex -scwq foo.txt
or for multiple files:
或者对于多个文件:
vi -es +"bufdo wq" *.txt
ex -s +"bufdo wq" *.txt
which automatically adds EOL at EOF on file save if it's missing.
如果文件丢失,它会自动在文件保存的 EOF 处添加 EOL。
To apply for certain files recursively, use a new globbing option(**
) such as **/*.txt
(enable by shopt -s globstar
).
要递归申请某些文件,请使用新的通配选项( **
),例如**/*.txt
(enable by shopt -s globstar
)。
回答by Isaac
tail -c1 file | read -r _ || echo >> file
gets the last character of the file pipes it into read
, which will exit with a nonzero exit code if it encounters EOF before newline (so, if the last character of the file isn't a newline). If read
exits nonzero, then append a newline onto the file using echo
(if read
exits 0, that satisfies the ||
, so the echo
command isn't run).
获取文件的最后一个字符通过管道将其导入read
,如果在换行符之前遇到 EOF 则它将以非零退出代码退出(因此,如果文件的最后一个字符不是换行符)。如果read
退出非零,则使用echo
(如果read
退出 0,则满足||
,因此echo
命令不会运行)追加到文件中的换行符。
From http://backreference.org/2010/05/23/sanitizing-files-with-no-trailing-newline/.
来自http://backreference.org/2010/05/23/sanitizing-files-with-no-trailing-newline/。
回答by dosentmatter
Using Bash only
仅使用 Bash
You can use Command Substitution (remove trailing newlines) with Here Strings (appends newline):
您可以将命令替换(删除尾随换行符)与此处字符串(附加换行符)一起使用:
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).
Here's how it works:
这是它的工作原理:
cat <<<"$(<inputfile)"
Output to file:
输出到文件:
cat <<<"$(<inputfile)" >outputfile
If you need inputfile
and outputfile
to be the same file name, you have a couple options - use sponge
command, save to temporary variable with more command substitution, or save to temporary file.
如果您需要inputfile
和outputfile
成为相同的文件名,您有几个选项 - 使用sponge
命令,使用更多命令替换保存到临时变量,或保存到临时文件。
Using Sed
使用 Sed
Others have suggested using
其他人建议使用
sed '$a\' inputfile
which appends nothing to the last line. This is fine, but I think
最后一行不添加任何内容。这很好,但我认为
sed '$q' inputfile
is a bit clearer, because it quits on the last line. Or you can do
更清楚一点,因为它在最后一行退出。或者你可以做
sed -n 'p'
which uses -n
to suppress output, but prints it back out with p
.
它用于-n
抑制输出,但使用p
.
In any of these cases, sed
will fix up the line and add a newline, at least for GNU and BSD sed. However, I'm not sure if this functionality is defined by POSIX. A version of sed
might just skip your line without a newline since a line is defined as
在任何这些情况下,sed
将修复该行并添加一个换行符,至少对于 GNU 和 BSD sed。但是,我不确定此功能是否由 POSIX 定义。一个版本sed
可能只是跳过没有换行符的行,因为一行被定义为
A sequence of zero or more non- characters plus a terminating character.