I thought of another way to do this that doesn't rely on paired lines but instead only a <space>
character following a \n
ewline character:
sed ':n;N;s/\n */ /;tn;P;D'
That uses a sliding window of newline data and the t
est function to operate. The flow is like this:
- define the
:n
ext label
- append
N
ext line in input to pattern space
s/
elect a \n
ewline character followed by 1 or more <space>
characters and replace them with a single /<space>/
t
est if last s///
was successful and, if so, branch to :n
ext label, else...
P
rint up to the first \n
ewline character in pattern space and...
D
elete up to and including first \n
ewline character in pattern space and restart cycle with remaining pattern space or with next line
So, basically, all occurrences of \n [ ]*
in input get squeezed into [ ]
:
sed ':n;N;s/\n */ /;tn;P;D' <<\DATA
2014-06-06 AAA
BBB
2014-06-06 CCC
DDD
2014-06-06 EEE
2014-06-06 FFF
GGG
DATA
OUTPUT:
2014-06-06 AAA BBB
2014-06-06 CCC DDD
2014-06-06 EEE
2014-06-06 FFF GGG
OLD:
sed -n 'h;n;H;x;s/\n */ /p' <<\DATA
2014-06-06 AAA
BBB
2014-06-06 CCC
DDD
DATA
OUTPUT:
2014-06-06 AAA BBB
2014-06-06 CCC DDD
I use 5 sed
commands.
- overwrite
h
old space with pattern space...
- overwrite pattern space with the
n
ext line in input
- append pattern space to
H
old space following an automatically inserted \n
ewline character
- e
x
change the contents of hold and pattern spaces
s/
elect the first \n
ewline character and any or *
all following spaces then /
replace the selection with a single space and /p
rint the result.
Though, now that I think about it, a simplified version of both mine and @Falsenames answers - which really is better than this one - would just be:
sed 'N;s/\n */ /' <<\DATA
2014-06-06 AAA
BBB
2014-06-06 CCC
DDD
DATA
OUTPUT:
2014-06-06 AAA BBB
2014-06-06 CCC DDD