There's no need to put the label :a
outside of the main instruction, neither is the -e
option necessary needed; finally, the /$/
is superfluous (every line has an EOL character).
Improving other answers, one gets
sed -i ':a; N; s/\n/ /; ta' file
Which is clearer if written as follows,
sed -i ':a
N
s/\n/ /
ta' file
The command works as follows:
N
appends the next line to the (multiline) pattern space, which contains the current line already;
s/\n/ /
substitute the newline character \n
generated by N
with a space
;
ta
goes to the script line following the label :a
as long as the substitution in step 2 was successful, i.e. if the substitution occurred, the execution jumps to step 1 without "hitting" the end of script, i.e. without reading another line of input.
Note the following;
sed
reads the lines of the input file one by one in order, starting from the 1st line;
:a
is just a label, not a command to be executed;
N
is, in principle, executed on any line, but
s/\n/ /
(in principle executed on any line) is successful on any line but the last one, so
ta
makes the end of the script reachable only when the last line of input is read (the only line where s
fails), so
- no further input line is read into the pattern space after the 1st one is read into it, unless the last one is read in, but then there's no further line to read in, and the implicit
p
command is executed.
So the script basically reads in the 1st line of input and keeps appending the following lines one by one, each time substituting the newline with a space; after the last line is appended (and \n
changed in a space), N
can't append any line, s
fails, ta
is skipped, the end of the script is reached, and the implied p
rint statement is executed on the current looong 1-line pattern space.
The -i
option substitutes the input file file
with the whole 1-line pattern space.