ganthdev
ganthdev

Reputation: 55

Sed/Awk: Delete all lines after last occurrence of pattern

I have a file with one insert on each line, like below:

INSERT INTO table (columns) values (1,x,b);
INSERT INTO table (columns) values (2,y,c);
INSERT INTO table (columns) values (3,w,d);
INSERT INTO table (columns) values (4,z,e);
-- Comment
SELECT * FROM table;
-- Comment
SELECT * FROM table;

How do I remove every line after the last ocurrence of INSERT INTO? Output I'm looking for is:

INSERT INTO table (columns) values (1,x,b);
INSERT INTO table (columns) values (2,y,c);
INSERT INTO table (columns) values (3,w,d);
INSERT INTO table (columns) values (4,z,e);

Upvotes: 4

Views: 1480

Answers (3)

Toby Speight
Toby Speight

Reputation: 30964

If you have an actual file rather than a stream, you can use an ed one-liner:

?^INSERT INTO?+,$d

This deletes (d) everything from the line after (+) the last that matches (?...?) the pattern ^INSERT INTO up to the last line ($).

Demo:

#!/bin/sh

filename=$(mktemp)

cat >>"$filename" <<'END'
INSERT INTO table (columns) values (1,x,b);
INSERT INTO table (columns) values (2,y,c);
INSERT INTO table (columns) values (3,w,d);
INSERT INTO table (columns) values (4,z,e);
-- Comment
SELECT * FROM table;
-- Comment
SELECT * FROM table;
END


ed -s "$filename" <<'END'
?^INSERT INTO?+,$d
wq
END


cat "$filename"
rm "$filename"

Upvotes: 0

ctac_
ctac_

Reputation: 2491

With gnu sed

If there is no comment before the last 'INSERT INTO'

sed -n '/INSERT INTO/{p;b};q' infile

If there are some comments before the last 'INSERT INTO'

sed -z 's/\(.*INSERT INTO[^\n]*\n\).*/\1/' infile

Upvotes: 0

Kent
Kent

Reputation: 195269

The easier way is to use tac:

tac file|sed '0,/^INSERT INTO/{/INSERT INTO/!d}'|tac

You can also use awk without tac:

awk 'NR==FNR{if(/^INSERT INTO/)e=NR;next}FNR<=e' file file

Upvotes: 3

Related Questions