Questioner
Questioner

Reputation: 7463

Why is sed not replacing this newline character?

I'm using sed in a Bash shell on Ubuntu to replace text in some files. Here is the text I have:

 BLah </V>
<N> Blah

Here is what I want to convert it to:

Blah" = "Blah

Here is the sed command I am using on it:

sed -i 's@ </V>\n<N> @" = "@g'

All my other sed commands are working except this one. This is the only search and replace situation where there is a newline character involved. The problem seems to be that \n isn't matching the new line character like I thought it should.

Where is my script going wrong?

Upvotes: 2

Views: 4184

Answers (2)

Lev Levitsky
Lev Levitsky

Reputation: 65781

The thing is that sed processes the text line by line. It doesn't have both line in its buffer (called pattern space) simultaneously. You can fix it by tweaking the script:

sed 'N;s@ </V>\n<N> @" = "@g'

From man sed:

   n N    Read/append the next line of input into the pattern space.

This is what N does: appends the next line to the pattern space. Then the substitution works.

Example:

$ sed 'N;s@ </V>\n<N> @" = "@g' <<<' BLah </V>
<N> Blah'
 BLah" = "Blah

This however will have a 50% chance of not working, depending on whether the pattern starts on an even or odd line in the input. To get around this, you can modify the script like this:

sed 'N;s@ </V>\n<N> @" = "@g;P;D'

Upvotes: 4

Ed Morton
Ed Morton

Reputation: 203149

sed is an excellent tool for simple substitutions on a single line, for any other text processing just use awk:

$ cat file
Blah </V>
<N> Blah

$ awk -v RS= 'sub(/ <\/V>\n<N> /,"\" = \"")' file
Blah" = "Blah

None of this hold pattern, transporter buffer in subspace or whatever stuff required - just set your Record Separator to something other than a newline and treat your multi-line string just like any other string.

Upvotes: 3

Related Questions