I have the following file:
line 1
abc
line 2
def
line 3
ghi
.....
.....
I need it to become:
line 1 abc
line 2 def
line 3 ghi
......
......
I know how to remove newlines, but not odd or even line breaks.
This might work for you (GNU sed):
sed -i 'N;s/\n/ /' file
Append the following line and replace the newline with a space.
Alternative using paste:
paste -sd' \n' file
In Vim, there are several ways to do this without having to leave the comfort of your favorite text editor.
:globalMatch every line and join with the next line.
The command :g/./ matches any non-blank line, i.e. it will yield correct results even if there are several paragraphs that need to be joined.
It can be prefixed with a range of lines to operate on (default: whole buffer).
It is followed by the :join command to join the following line.
As :global "walks" through the buffer from top to bottom, it will skip the just-joined line.
:[range]g/./j
See :help :global and :help :join.
You can record the command to join lines (J) and then proceed to the next line (j).
These two commands can be recorded into a register (e.g. a) and replayed as explained in :help complex-repeat:
qaJjq
Replay twice with 2@a.
To operate on all lines of the buffer, record a recursive macro like this:
qaqqaJj@aq
And replay with @a.
Explanation:
qaq records an empty macro, effectively clearing register a so nothing happens when we call it during recording.
qaJj starts recording and does the join-advance steps.
@a is the recursive macro call to the (still empty) register a.
q finishes recording and a is now ready to be run.
This is cheating a little bit as we let Vim filter the current buffer through an external command. This means we can easily leverage any of the other solutions (as long as we remember to escape any special character).
Using the first solution from Ed Morton's answer, we would run:
:%!awk 'NR\%2{p=$0; next} {print p, $0}'
Note that the % needed to be escaped.
The reference documentation is found in :help :range!.
I would harness GNU AWK for this task following way, let file.txt content be
line 1
abc
line 2
def
line 3
ghi
.....
.....
then
awk '{printf("%s%s",$0,NR%2?" ":"\n")}' file.txt
gives output
line 1 abc
line 2 def
line 3 ghi
..... .....
Explanation: I use printf and so-called ternary operator. First part is always whole line ($0) second part is space if remainder of division of number of line is non-zero (i.e. line is odd) and newline otherwise.
(tested in GNU Awk 5.3.1)
Using any awk:
<PS1> awk 'NR%2{p=$0; next} {print p, $0}' file
line 1 abc
line 2 def
line 3 ghi
..... .....
<PS1>
<PS1> awk 'NR%2{printf "%s", $0; next} {print OFS $0}'
line 1 abc
line 2 def
line 3 ghi
..... .....
<PS1>
<PS1> awk 'NR%2{p=$0; next} {print p, $0} END{if (NR%2) print p}' file
line 1 abc
line 2 def
line 3 ghi
..... .....
<PS1>
There are other possibilities too but the right answer all depends on how you want input that has an odd number of lines handled because while they all produce the same output given the sunny-day case of an even number of input lines, as shown above, they'll each do different things given the rainy-day case of an odd number of input lines:
<PS1> seq 5 | awk 'NR%2{p=$0; next} {print p, $0}' | cat -e
1 2$
3 4$
<PS1>
<PS1> seq 5 | awk 'NR%2{printf "%s", $0; next} {print OFS $0}' | cat -e
1 2$
3 4$
5<PS1>
<PS1> seq 5 | awk 'NR%2{p=$0; next} {print p, $0} END{if (NR%2) print p}' | cat -e
1 2$
3 4$
5$
<PS1>
To learn awk, get the book Effective AWK Programming, 5th Edition, by Arnold Robbins.
Don't waste time doing modulos when none are required. Just keep inverting a boolean flag :
echo 'line 1
abc
line 2
def
line 3
ghi' |
awk 'ORS = (_ = !_) ? FS : RS'
line 1 abc
line 2 def
line 3 ghi
sed solutions, mine doesn't even need to temporarily store the current row; unlike other awk solutions, mine doesn't require performing modulo-ops; and unlike other vim solutions, mine doesn't require generating cryptic macro sequences like qaqqaJj@aqawk 'ORS = ORS < FS ? FS : RS'is_odd would be meaningfulORS = (is_odd = ! is_odd) ? … : … is all that clear to the reader ? :::::::::: :::::::: is_odd <— not is_odd sounds very clunky to me.Use this Perl one-liner:
perl -lne 'if ( $. % 2 ) { $prev = $_; print if eof; } else { print "$prev $_"; }' infile
Even number of input lines:
seq 1 10 | perl -lne 'if ( $. % 2 ) { $prev = $_; print if eof; } else { print "$prev $_"; } '
Output:
1 2
3 4
5 6
7 8
9 10
Odd number of input lines:
seq 1 9 | perl -lne 'if ( $. % 2 ) { $prev = $_; print if eof; } else { print "$prev $_"; }'
Output:
1 2
3 4
5 6
7 8
9
The Perl one-liner uses these command line flags:
-e : Tells Perl to look for code in-line, instead of in a file.
-n : Loop over the input one line at a time, assigning it to $_ by default.
-l : Strip the input line separator ("\n" on *NIX by default) before executing the code in-line, and append it when printing.
$. : Current input line number.
eof : End of file. A test for this (and the subsequent print) is needed for printing the last line if the input in case the number of lines is odd.
awk:awk 'NR%2{curr=$0; getline; print curr,$0}' fileawk 'NR%2 {getline n; print $0, n}'