Philippe Chartrand
Philippe Chartrand

Reputation: 1

delete lines if firstline matches expression, but next 2 lines do not match different expression

I have a test file in this format:

G03X22Y22.5
G01X48.5
M98P9001 (OFF)****
G00X20Y25
M98P8051 (FAST CUT)
G01X22Y34
G01X25Y33

I am trying to make a bash or MSDOS script that will :

Find all lines in the file that match : M98P9001

if the NEXT 2 LINES do not contain the code { M98P8050, M98P8080 OR M09 } Delete all 3 lines . which would result in the output :

G03X22Y22.5
G01X48.5
G01X22Y34
G01X25Y33

I've tried solutions with SED or AWK, but haven't gotten the right one yet:

sed -e '/M98P9001/,+2d' input.txt >> output.txt

this one will always delete all 3 lines after finding the match , but I need to only delete the lines if the next 2 lines following the match do not have a match with { M98P8050, M98P8080 OR M09 }.

Upvotes: 0

Views: 48

Answers (3)

potong
potong

Reputation: 58371

This might work for you (GNU sed):

sed -E ':a;N;s/\n/&/2;Ta;/^[^\n]*M98P9001/{/\n.*(M98P8050|M98P8080|M09)/!d};P;D' file

Open a three line window throughout the length of the file.

If the first line of the window contains M98P9001 and either of the second or third lines do not contain M98P8050, M98P8080 or M09 delete the entire window and repeat.

Otherwise, print/delete the first line of the window and repeat.

N.B. The idiom :a;N;s/\n/&/2;Ta tops up the three line window.

Upvotes: 1

David784
David784

Reputation: 7464

This seems to give your desired output:

awk '
  /M98P9001/ { 
    getline l2; getline l3;
    if((l2 l3)~/M98P8050|M98P8080|M09/) printf "%s\n%s\n%s\n", $0, l2, l3; 
    next; 
  } 
  { print; }'

Description:

  • If first line pattern match, read in next two lines to variables.
  • Check concatenation of both lines for any of the 3 secondary patterns
  • If match, print all three lines, else print nothing.
  • go to next record.
  • on all other lines, print.

Upvotes: 1

karakfa
karakfa

Reputation: 67467

a mark and sweep approach

$ awk 'NR==FNR {if(!(/M98P80[58]0|M09/ && p~/M98P80[58]0|M09/) && pp~/M98P9001/)
                 {a[NR]; a[NR-1]; a[NR-2]} 
                pp=p; p=$0; next} 
       !(FNR in a)' file{,}


G03X22Y22.5
G01X48.5
G01X22Y34
G01X25Y33

Upvotes: 2

Related Questions