Muralitharan Perumal
Muralitharan Perumal

Reputation: 173

Replacing multiple line using sed command

I have a text file file.log contains following text

file.log

ab
cd
ef

I want to replace "ab\ncd" with "ab\n" and the final file.log should look like this:

ab

ef

This is the sed command I am using but it couldn't recognize the newline character to match the pattern:

sed -i 's/\(.*\)\r   \(.*\)/\1\r/g' file.log

with 3 character space after '\r' but no change is made with this.

\(.*\) - This matches any character(.) followed by 0 or more (*) of the preceding character \r - For newline \1 - Substitution for the first matching pattern. In this case, it's 'ab'

Can you help me out what's wrong with the above command.

Upvotes: 1

Views: 171

Answers (3)

glenn jackman
glenn jackman

Reputation: 247250

A couple of other options:

perl -i -0pe 's/^ab\n\Kcd$//mg' file.log

which will change any such pattern in the file

If there's just one, good ol' ed

ed file.log <<END_SCRIPT
/^ab$/+1 c

.
wq
END_SCRIPT

Upvotes: 0

nu11p01n73R
nu11p01n73R

Reputation: 26687

The issue is that, the sed is a stream editor, which reads line by line from the input file

So when it reads line

ab

from the input file, it doesnt know whether the line is followed by a line

cd

When it reads the line cd it sed will habe removed the line ab from the pattern space, this making the pattern invalid for the current pattern space.

Solution

A solution can be to read the entire file, and append them into the hold space, and then replace the hold space. As

$ sed -n '1h; 1!H;${g;s/ab\ncd/ab\n/g;p}' input
ab

ef

What it does

  • 1h Copies the first line into the hold space.

  • 1!H All lines excpet the first line (1!) appends the line to the hold space.

  • $ matches the last line, performs the commands in {..}

  • g copies the contents of hold space back to pattern space

  • s/ab\ncd/ab\n/g makes the substitution.

  • p Prints the entire patterns space.

Upvotes: 1

Avinash Raj
Avinash Raj

Reputation: 174874

Sed processes the input file line by line. So can't do like the above . You need to include N, so that it would append the next line into pattern space.

$ sed 'N;s~ab\ncd~ab\n~g' file
ab

ef

Upvotes: 1

Related Questions