Print all EXCEPT content matching a range pattern with awk

In Awk, a range pattern is not an expression, so canot uses "!" Not this. so how to implement it (printing all EXCEPT contents of a matching range pattern using awk)?

eg.

$ cat 1.t

abd hfdh # fafa deafa 123 # end 

the result I wanted:

cat 1.t

 abd hfdh end 

EDIT:

I gave a daring example. endpattern should be different from the initial template because I just did not test this. It's my fault.

At the same time, I want to use the range pattern and the range pattern differently. Therefore sed is not my choice.

+4
source share
3 answers

you just gave a complex (I donโ€™t know what I should call it good or bad ^ _ ^) example. Your text has exactly the same startpattern and endpattern ( # )

I think you are looking for the same thing as sed '/#/,/#/d' or sed -n '/#/,/#/!p'

In awk, there is some similiar (not the same as sed) address model. There is an explanation on the man page. I did not say the same, your example is good. if start == end the address model for awk will not work:

 kent$ echo "abd hfdh # fafa deafa 123 # end"|awk '/#/,/#/{next}1' abd hfdh fafa deafa 123 end 

because awk matches the same line (check the man page again), but if they are different, see this example:

 kent$ echo "abd hfdh # fafa deafa 123 ## end"|awk '/#/,/##/{next}1' abd hfdh end 

he will give what you want. therefore, if so, you can simply do:

 awk '/start/,/end/{next}1' 

yes, very similar to sed.

If the start and end are really the same, you want to do it with awk, you need a flag.

 kent$ echo "abd hfdh # fafa deafa 123 # end"|awk '/#/&&!f{f=1;next}f&&/#/{f=0;next}!f' abd hfdh end 

well, in the example itโ€™s better to use ^#$ , but thatโ€™s not the point. Hope this answers your question.

+6
source

Is there an alternative?

 $ sed '/#/,/#/d' input abd hfdh end 
0
source

If you really need to use awk , something like this should work:

 awk 'BEGIN{x=1} /startpattern/{x=0} /endpattern/{x=1;next} x{print}' 

Although an alternative to sed may be a simpler approach (this is at least a less typical one).

Edit: @Kent indicated that you have the same start and end pattern, which makes it a little more complicated, but this should work:

 awk 'BEGIN{x=1} /pattern/{x=!x;next} x{print}' 

This basically switches x every time it sees a pattern, and only prints when x!=0 . next there avoids printing the template when you re-enable printing. A.

0
source

All Articles