There are actually two questions on your post:
Can sed replace new line characters?
Yes. Absolutely yes. Any sed could do:
s/\n/,/g
or
y/\n/,/
That will transform any newline (that got into the pattern space) into commas.
Is there an issue with sed and new line character?
Yes, there are several issues with the newline character in sed:
- By default, sed will place in the pattern space a valid line. Some seds have limits on the length of a line and on accepting NUL bytes. A line ends on a newline. So, as soon as a newline is found on the input, the input gets split, then sed removes the newline and places what is left in the pattern space. So, most of the time, no newline gets into the pattern space.
- Only by an edit of the pattern space is a newline added/inserted/edited in.
- Almost always, a newline is appended to each consecutive output of sed.
- The GNU sed is able to avoid printing a trailing newline if the last line of the input is missing the newline.
- Only GNU sed is able to use another delimiter instead of newline (namely NUL bytes with the -z option).
All the above points make it difficult to "convert newlines" to anything.
And, if newlines are replaced with another text character, then sed must contain the whole text file in memory (whatever process was used to get there).
A couple of solutions that capture the whole file in memory in sed are:
sed 'H;1h;$!d;x;y/\n/,/' file # most seds. [1]
sed ':a;N;$!ba;s/\n/,/g' file # GNU sed.
sed -z 's/\n/,/g;s/,$/\n/' file # GNU sed.
A couple of fast solutions that doesn't use much memory are:
tr '\n' ',' file ; echo
awk '{printf("%s%s",NR==1?"":",",$0)}END{print ""}' file
1From sed solutions: For every line, H adds the line to the hold space (except that the first line completely replace the hold space (avoid a leading newline)), then the pattern space is erased with $!d
(except on the last line). On that last line, which was not erased, the rest of commands gets executed. First, get all the lines captured in the hold space with x
and then, replace all newlines with a comma with y/\n/,/
.
tr
would add a trailing,
and would output an unterminated line. Best is to usepaste
instead:paste -sd , test.txt