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 liness/(Size=)bar/\1foo/
: MatchSize=bar
and 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