How to replace(or modify) the next record after a pattern matching? Ex:
1
2
3 blah
4 replace this record
5 blah
6 replace this record
7
8
9
Here I want to skip or replace the fourth record and 6th record when the previous one record is "blah"
This replaces the line after blah
:
$ awk 'f{$0="replacement"; f=0} /blah/{f=1} 1' file
1
2
3 blah
replacement
5 blah
replacement
7
8
9
f{$0="replacement"; f=0}
If f
is true (nonzero), then replace the line and reset f
to zero.
/blah/{f=1}
If this line matches the regex blah
, then set f
to true.
1
This is awk's cryptic shorthand for print-the-whole-line.
Using GNU sed
rather than awk
:
sed -e '/blah/{ n; c\' -e 'replacement' -e '}' file
This looks for the lines matching the pattern blah
. When such a line is found, it is printed with n
, which also immediately reads the next line of input. That next line is then changed with c
to the replacement text. Thie replacement text is printed at the end of the cycle.
Annotated sed
script:
/blah/ { ;# this is a "blah" line
n ;# output line and read next line
# change the line just read
c\
replacement
}
# (implicitly print all lines)
This sed
script would also work with sed
in both OpenBSD and NetBSD even though the one-liner at the top does not work with these implementations due to something that they do wrong with the c
command, it seems.
$ awk '/blah/ {print $0 "\n" "replacement"; getline; next} 1' file
If the current line matches blah
then print it, print replacement
on a new line, get the next line of output (which we already replaced with "replacement") and do nothing with it, and then skip the remaining rule. The "remaining rule" (which is only applied to lines that don't match blah
and don't follow a line matching blah) is to simply print the line.