Delete lines before and after a match in bash (with sed or awk)?

I am trying to remove two lines on one side of the pattern matching from a file full of transactions. I.e. find the match, then delete two lines in front of it, then delete two lines on it and then delete the match. Write this back to the source file.

So the input

D28/10/2011
T-3.48
PINITIAL BALANCE
M
^

and my pattern

sed -i '/PINITIAL BALANCE/,+2d' test.txt

However, this is only deleting two lines after a pattern match, and then removing the pattern match. I can’t work out a logical way to remove all 5 lines of data from the source file using sed.

+5
source share
5 answers

sed will do this:

sed '/\n/!N;/\n.*\n/!N;/\n.*\n.*PINITIAL BALANCE/{$d;N;N;d};P;D'

This works as follows:

  • If sed has only one line in the template space, it concatenates the other
  • ,
  • LINE + LINE + LINE BALANCE, ,
  • ,

, script:

sed '1{/PINITIAL BALANCE/{N;N;d}};/\n/!N;/\n.*\n/!N;/\n.*\n.*PINITIAL BALANCE/{$d;N;N;d};P;D'

, PINITIAL BALANCE , . =)

+4

awk :

awk '/PINITIAL BALANCE/{for(x=NR-2;x<=NR+2;x++)d[x];}{a[NR]=$0}END{for(i=1;i<=NR;i++)if(!(i in d))print a[i]}' file

:

kent$  cat file
######
foo
D28/10/2011
T-3.48
PINITIAL BALANCE
M
x
bar
######
this line will be kept
here
comes
PINITIAL BALANCE
again
blah
this line will be kept too
########

kent$  awk '/PINITIAL BALANCE/{for(x=NR-2;x<=NR+2;x++)d[x];}{a[NR]=$0}END{for(i=1;i<=NR;i++)if(!(i in d))print a[i]}' file
######
foo
bar
######
this line will be kept
this line will be kept too
########

  awk '/PINITIAL BALANCE/{for(x=NR-2;x<=NR+2;x++)d[x];}   #if match found, add the line and +- 2 lines' line number in an array "d"
      {a[NR]=$0} # save all lines in an array with line number as index
      END{for(i=1;i<=NR;i++)if(!(i in d))print a[i]}' #finally print only those index not in array "d"
     file  # your input file
+6

, , , Perl:

perl -ne 'push @x, $_;
          if (@x > 4) {
              if ($x[2] =~ /PINITIAL BALANCE/) { undef @x }
                  else { print shift @x }
          }
          } END { print @x'
+1

(GNU sed):

sed ':a;$q;N;s/\n/&/2;Ta;/\nPINITIAL BALANCE$/!{P;D};$q;N;$q;N;d' file
+1

grep.sed

H
s:.*::
x
s:^\n::
:r
/PINITIAL BALANCE/ {
    N
    N
    d    
}

/.*\n.*\n/ {
    P
    D
}
x
d

:

`sed -i -f grep.sed FILE`

:

sed -i 'H;s:.*::;x;s:^\n::;:r;/PINITIAL BALANCE/{N;N;d;};/.*\n.*\n/{P;D;};x;d' FILE
0

All Articles