为什么sed在OSX中添加新行?

时间:2012-11-10 19:02:33

标签: macos sed

echo -n 'I hate cats' > cats.txt
sed -i '' 's/hate/love/' cats.txt

这会正确更改文件中的单词,但也会在文件末尾添加换行符。为什么?这只发生在OSX中,而不是Ubuntu等。我该如何阻止它?

5 个答案:

答案 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

如果您需要一个不会添加换行符的解决方案,可以使用gsedbrew 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"