2

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 3

2

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.

Sign up to request clarification or add additional context in comments.

Comments

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.