Issue
Given the following file:
temp.txt
line1
line2
line3
line4
line5
line6
line7
And the following bash/sed commands:
for (( i=0; i<6; i++ ))
do
sed "N;1s/\\(.\*\\)\n\\(.\*\\)/\1 \2/" temp.txt
done
doesn't produce the desired stout:
line1 line2 line3 line4 line5 line6
line7
Thanks in advance for any insight you can provide.
Solution
Your code is:
for (( i=0; i<6; i++ ))
do
sed "N;1s/\(.*\)\n\(.*\)/\1 \2/" temp.txt
done
N
tells sed to read the next line. By doing so the current line number is incremented. So testing for line 1 can never succeed. (You should test for line 2.)- You have not used
-i
and so the file will not be changed. - It is rather inefficient to call sed 6 times instead of just doing everything in a single invocation. (And you should only call it 5 times to join 6 lines.)
A simpler alternative:
sed -i '1{N;N;N;N;N;s/\n/ /g;}' temp.txt
In the case that the input could have fewer than 6 lines and up to 6 lines should be joined, an alternative script is:
sed -i ':a;$q;N;1,6s/\n/ /;ta' temp.txt
Note that BSD-ish sed requires a literal newline after any label.
Behaviour of N
when there is no next line varies between implementations. Some output the existing contents of the pattern space, others follow posix and discard it. (GNU sed will do either: seq 3 | sed N
vs seq 3 | sed --posix N
.) Prefixing $q
sidesteps this ambiguity and forces output.
Answered By - jhnc Answer Checked By - David Goodson (WPSolving Volunteer)