1

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"

John1024
  • 74,655
var
  • 11

3 Answers3

3

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

How it works

  • 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.

John1024
  • 74,655
1

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.

Kusalananda
  • 333,661
0
$ 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.