echo -n 'I hate cats' > cats.txt
sed -i '' 's/hate/love/' cats.txt
这会正确更改文件中的单词,但也会在文件末尾添加换行符。为什么?这只发生在OSX中,而不是Ubuntu等。我该如何阻止它?
答案 0 :(得分:8)
echo -n 'I hate cats' > cats.txt
此命令将使用单引号之间的11个字符填充'cats.txt'的内容。如果你在这个阶段检查cats.txt的大小,它应该是11个字节。
sed -i '' 's/hate/love/' cats.txt
此命令将逐行读取cats.txt文件 ,并将其替换为文件,其中每行已将第一个“hate”实例替换为'爱'(如果存在这种情况)。重要的是要了解一条线是什么。从sed手册页:
Normally, sed cyclically copies a line of input, not including its
terminating newline character, into a pattern space, (unless there is
something left after a ``D'' function), applies all of the commands
with addresses that select that pattern space, copies the pattern
space to the standard output, appending a newline, and deletes the
pattern space.
请注意appending a newline
部分。在您的系统上,即使没有终止换行符,sed仍将您的文件解释为包含一行。因此输出将是11个字符,加上附加的换行符。在其他平台上,情况不一定如此。有时sed将完全跳过文件中的最后一行(实际上删除它),因为it is not really a line!但在你的情况下,sed基本上是为你修复文件(作为一个没有行的文件,它是对sed的输入断开)。
在此处查看更多详情:Why should text files end with a newline?
有关问题的替代方法,请参阅此问题:SED adds new line at the end
如果您需要一个不会添加换行符的解决方案,可以使用gsed
(brew install gnu-sed
)
答案 1 :(得分:1)
请注意,GNU sed不会在Mac OS上添加换行符。
答案 2 :(得分:1)
避免此问题的一个好方法是使用perl而不是sed。 Perl将尊重原始文件中的EOF换行符或缺少换行符。
echo -n 'I hate cats' > cats.txt
perl -pi -e 's/hate/love/' cats.txt
答案 3 :(得分:0)
你可以做的另一件事是:
echo -n 'I hate cats' > cats.txt
SAFE=$(cat cats.txt; echo x)
SAFE=$(printf "$SAFE" | sed -e 's/hate/love/')
SAFE=${SAFE%x}
这样,如果cats.txt以换行符结尾,则会被保留。如果没有,则不会添加一个。
答案 4 :(得分:0)
这对我有用。我没有必要使用中间文件。
OUTPUT=$( echo 'I hate cats' | sed 's/hate/love/' )
echo -n "$OUTPUT"