Why does sed add a new line in OSX?

为君一笑 提交于 2020-02-18 07:24:08

问题


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

This changes the word in the file correctly, but also adds a newline to the end of the file. Why? This only happens in OSX, not Ubuntu etc. How can I stop it?


回答1:


echo -n 'I hate cats' > cats.txt

This command will populate the contents of 'cats.txt' with the 11 characters between the single quotes. If you check the size of cats.txt at this stage it should be 11 bytes.

sed -i '' 's/hate/love/' cats.txt

This command will read the cats.txt file line by line, and replace it with a file where each line has had the first instance of 'hate' replaced by 'love' (if such an instance exists). The important part is understanding what a line is. From the sed man page:

 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.

Note the appending a newline part. On your system, sed is still interpreting your file as containing a single line, even though there is no terminating newline. So the output will be the 11 characters, plus the appended newline. On other platforms this would not necessarily be the case. Sometimes sed will completely skip the last line in a file (effectively deleting it) because it is not really a line! But in your case, sed is basically fixing the file for you (as a file with no lines in it, it is broken input to sed).

See more details here: Why should text files end with a newline?

See this question for an alternate approach to your problem: SED adds new line at the end

If you need a solution which will not add the newline, you can use gsed (brew install gnu-sed)




回答2:


A good way to avoid this problem is to use perl instead of sed. Perl will respect the EOF newline, or lack thereof, that is in the original file.

echo -n 'I hate cats' > cats.txt
perl -pi -e 's/hate/love/' cats.txt



回答3:


Note that GNU sed does not add the newline on Mac OS.




回答4:


Another thing you can do is this:

echo -n 'I hate cats' > cats.txt
SAFE=$(cat cats.txt; echo x)
SAFE=$(printf "$SAFE" | sed -e 's/hate/love/')
SAFE=${SAFE%x}

That way if cats.txt ends in a newline it gets preserved. If it doesn't, it doesn't get one added on.




回答5:


This worked for me. I didn't have to use an intermediate file.

OUTPUT=$( echo 'I hate cats' | sed 's/hate/love/' )
echo -n "$OUTPUT"


来源:https://stackoverflow.com/questions/13325138/why-does-sed-add-a-new-line-in-osx

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!