awk remove before match but after empty line

Viewed 60

I didn't find the exact similar question, so i need to ask:

I have a file gist :

...
must_be_intact

bad_line
bad_line
bad_line
match_line
...

I use awk to remove everything before the match but after a space:

'NR==FNR{if (/match_line/) { 
    i=0;
    while(1) {
        if (NR-i==/^\s*$/) break; 
        del[NR-i]; 
        i=i-1; 
        next
        }
    }
} !(FNR in del)'

But this does not work correctly. Help improve this code, or you can advise another way.

3 Answers

You have overcomplicated it.

You can just use tac + awk + tac operations:

tac file | awk '/^match_line$/,!NF{next} 1' | tac
must_be_intact

must_be_intact
must_be_intact
must_be_intact

must_be_intact
must_be_intact
must_be_intact

must_be_intact

must_be_intact

must_be_intact
must_be_intact

must_be_intact
must_be_intact
must_be_intact

This awk uses a range from NF==0 (indicating empty line) to a line that just has match_line and uses next in action block to skip that part.

With your shown samples only, please try following awk code, written and tested in GNU awk. Simple explanation would be, setting RS(record separator) as 1 or more occurrences of new lines till match_line and in main program; substituting first new line with NULL and then printing the lines as per RS.

awk -v RS='\n+.*match_line' '{sub(/\n/,"")}1' Input_file
$ sed '/^$/,/match_line/{/match_line/!d}' txt
...
must_be_intact
match_line
...

Or

awk -v m="match_line" '{ if($0 ~ /^$/) { while($0 != m) getline } print }' txt

Which yields the same output. I can edit/elaborate later if you want, now I have to go! :)

Related