Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does sed add a new line in OSX?

Tags:

macos

sed

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?

like image 310
Will Hamilton Avatar asked Nov 10 '12 19:11

Will Hamilton


3 Answers

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)

like image 199
Zac Thompson Avatar answered Nov 11 '22 15:11

Zac Thompson


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
like image 42
Mike Morearty Avatar answered Nov 11 '22 15:11

Mike Morearty


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

like image 1
Dave Griffiths Avatar answered Nov 11 '22 13:11

Dave Griffiths