echo "hi,my,name,is" | sed 's/,/\n/g' >out.txt
yields:
hi
my
name
is
But in reverse:
sed 's/\n/,/g' out.txt
yields:
hi
my
name
is
Why doesn't sed
revert the operation with an inversion of the replace operation?
echo "hi,my,name,is" | sed 's/,/\n/g' >out.txt
yields:
hi
my
name
is
But in reverse:
sed 's/\n/,/g' out.txt
yields:
hi
my
name
is
Why doesn't sed
revert the operation with an inversion of the replace operation?
Try:
$ sed 'H;1h;$!d;x; s/\n/,/g' out.txt
hi,my,name,is
By default, sed reads in only one line at a time, processes it, and prints it. Since a single line never has a newline character, the command s/\n/,/g
does nothing. The solution, as above, is to read the whole file in at once and then do s/\n/,/g
.
The commands H;1h;$!d;x
read the whole file in at once. It is probably
simplest to think of this as an idiom. If you really want to know
the gory details:
H
- Append current line to hold space1h
- If this is the first line, overwrite the hold space
with it$!d
- If this is not the last line, delete pattern space
and jump to the next line.x
- Exchange hold and pattern space to put whole file in
pattern space$ awk 'NR>1{printf ","} {printf "%s",$0} END{print""}' out.txt
hi,my,name,is
Or:
$ awk '{printf "%s%s",(NR==1?"":","),$0} END{print""}' out.txt
hi,my,name,is
tr
approach. He was looking for a better understanding of sed
.
– John1024
Mar 09 '18 at 04:18
{printf "%s",t $0; t=","} END{print""}
or {t=t "," $0} END{print substr(t,2)}
optionally with redundant BEGIN{t=""}
or -vt=
for clarity; or on condition none of the lines are empty -vRS="" '{gsub(/\n/,","); print}'
(which is almost like the sed)
– dave_thompson_085
Mar 09 '18 at 06:03