Someone came to my website by way of the search engine query:
sed replace return with comma
It's an interesting dilemma. There are two obstacles to doing this in sed. One is that sed operates line by line and never sees the newline endings. Second, sed's regular expressions don't provide a way to exactly match a newline character.
If you really want to do this, don't use sed; use tr
.
cat file | tr '\n' ','
But let's work with sed. We can regain the newlines by appending
each line onto the hold space. (Again, if you want efficient, use tr.)
Then you can convert all the whitespace characters with
the POSIX character class [:space:]
. But, of course,
the text probably contains spaces and tabs that you don't want to
convert. So you have to change those to something innocuous first,
convert what's left, and change the spaces and tabs back.
This code changes every space to {{{{space}}}}
and
every tab to {{{{tab}}}}
; stores the first line in
the hold space; appends every other line to the hold space;
and on the last line it changes all the remaining whitespace
characters to a comma, then the space-markers and the tab-markers
back to spaces and tabs.
s/ /{{{{space}}}}/g s/ /{{{{tab}}}}/g 1h 2,${H} ${g;s/[[:space:]]/,/g; s/{{{{space}}}}/ /g;s/{{{{tab}}}}/ /g;p}
There remains a problem with line feeds and any other whitespace besides newline, space, and tab. I can't find details on what [:space:] actually includes, but it seems to be locale-specific. If you have form feeds in your input, you'll need to escape them like we did the spaces and tabs.
Pleasantly, unlike a newline, form feeds can be inserted meaningfully
into sed code (using something like
quoted-insert
(C-q) in Emacs).
Then they can be manipulated just like spaces and tabs.
s/ /{{{{space}}}}/g s/ /{{{{tab}}}}/g s//{{{{form-feed}}}}/g 1h 2,${H} ${g;s/[[:space:]]/,/g; s/{{{{space}}}}/ /g; s/{{{{tab}}}}/ /g; s/{{{{form-feed}}}}//g;p}
We can match the newline character using shell substitution, but
I can't get 1h;2,$H;...
to work, so this code creates an
extraneous leading comma.
sed -n -e "H;\${g;s/\n/,/g;p}" foo.txt
Mr. Stolz wrote and provides the correction:
sed -n '1h;2,$H;${g;s/\n/,/g;p}' foo.txt