Home > other >  awk remove before match but after empty line
awk remove before match but after empty line

Time:02-10

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.

CodePudding user response:

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.

CodePudding user response:

$ 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! :)

CodePudding user response:

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