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$/, 2Match range from pattern#ABCto next 2 liness/(Size=)bar/\1foo/: MatchSize=barand replace withSize=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
