Sed – Replacing Lines Containing a Pattern

sed

How can I replace a given character in a line matching a pattern with sed?

For example: I'd like to match every line beginning with a letter, and replace the newline at the end with a tab. I'm trying to do so using: sed -e '/^[A-Z]/s/\n/\t/g' (the lines that I'm interested in also ALWAYS end with a letter, if this can help).

Sample input

NAME_A
12,1
NAME_B
21,2

Sample output

NAME_A    12,1
NAME_B    21,2

Best Answer

sed '/^[[:alpha:]]/{$!N;s/\n/       /;}' <<\DATA
NAME_A
12,1
NAME_B
21,2
DATA

OUTPUT

NAME_A  12,1
NAME_B  21,2

That addresses lines beginning with a letter, pulls in the next if there is one, and substitutes a tab character for the newline.

note that the s/\n/<tab>/ bit contains a literal tab character here, though some seds might also support the \t escape in its place

To handle a recursive situation you need to make it a little more robust, like this:

sed '$!N;/^[[:alpha:]].*\n[^[:alpha:]]/s/\n/    /;P;D' <<\DATA
NAME_A
NAME_B
12,1  
NAME_C
21,2
DATA

OUTPUT

NAME_A
NAME_B  12,1
NAME_C  21,2

That slides through a data set always one line ahead. If two ^[[:alpha:]] lines occur one after the other, it does not mistakenly replace the newline, as you can see.

Related Question