Home > Blockchain >  How to replace 2 consecutive lines after Match with Sed
How to replace 2 consecutive lines after Match with Sed

Time:04-02

Is there a way to replace the following two lines after a match is found using sed?

I have a file

#ABC
oneSize=bar
twoSize=bar
threeSize=foo

But I would like to replace the two immediate lines once the pattern #ABC is matched so that it becomes

#ABC
oneSize=foo
twoSize=foo
threeSize=foo

I'm able to do gsed '/^#ABC/{n;s/Size=bar/Size=foo/}' file

But it only changes the line twoSize not oneSize

Is there a way to get it to change both oneSize and twoSize

CodePudding user response:

You can repeat the commands:

gsed '/^#ABC/{n;s/Size=bar/Size=foo/;n;s/Size=bar/Size=foo/}' file

See the online demo.

The n command "prints the pattern space, then, regardless, replace the pattern space with the next line of input. If there is no more input then sed exits without processing any more commands."

So, the first time it is used, you replace on the first line after line starting with #ABC, then you replace on the second line below that one.

CodePudding user response:

gnu and some other sed versions allow you to grab a range using relative number so you can simply use:

sed -E '/^#ABC$/, 2 s/(Size=)bar/\1foo/' file
#ABC
oneSize=foo
twoSize=foo
threeSize=foo

Command details:

  • /^#ABC$/, 2 Match range from pattern #ABC to next 2 lines
  • s/(Size=)bar/\1foo/: Match Size=bar and replace with Size=foo, using a capture group to avoid repeat of same String in search and substitution

You may also consider awk to avoid repeating pattern and replacements N times if you have to replace N lines after matching pattern:

awk 'n-- {sub(/Size=bar/, "Size=foo")} /^#ABC$/ {n=2} 1' file

#ABC
oneSize=foo
twoSize=foo
threeSize=foo

CodePudding user response:

Using sed, the loop will break when Size=bar is no longer found therefore replacing the first 2 lines after the match.

$ sed '/^#ABC/{:l;n;s/Size=bar/Size=foo/;tl}' input_file
#ABC
oneSize=foo
twoSize=foo
threeSize=foo
  • Related