Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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
share|improve this question

2 Answers 2

up vote 6 down vote accepted
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.

share|improve this answer
    
please also upvote the question - it is a good one. –  mikeserv Jul 29 at 8:41

Another solution:

sed -e :a -e '$!N;s/\n\([^[:alpha:]]\)/ \1/;ta' -e 'P;D'

This append current line to previous line if it not start with alphabeta.

Updated

A solution by @mikerserv after our discussion:

sed ':a
/^[[:alpha:]]/{$!N;/\n[^[:alpha:]]/!ba;s/\(.*\)\n/\1\t/}
' file

Explanation

On a line that starts with an alphabetic character, it pulls in the next if there is one, then, if it can address a newline followed by a non-alphabetic character, it selects everything in pattern space up to the last newline there and does a substitute on it - changing the last new line to a tab. But if not it branches back and tries again.

share|improve this answer
    
But what if the previous line didn't start with [[:alpha:]]? –  mikeserv Jul 29 at 8:48
    
This will concat consecutive lines does not start with [[:alpha:]]. –  Gnouc Jul 29 at 8:50

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.