Printing all contents EXCEPT matching range pattern using awk

前端 未结 3 1917
滥情空心
滥情空心 2021-01-13 11:12

In Awk, the range pattern is not an expression, so canot use the \"!\" to not it. so how to implement it (Printing all contents EXCEPT matching range pattern using awk)?

相关标签:
3条回答
  • 2021-01-13 11:41

    you just gave a tricky (I don't know I should call it good or bad ^_^ ) example. Your text have exactly same startpattern and endpattern (#)

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

    There is some similiar (not same as sed's) address model in awk. In man page there is explanation. I said not same, your example is good one. if start == end the address model for awk won't work:

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

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

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

    it will give what you want. so if this is the case, you could just do:

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

    yes, quite similar as sed's one.

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

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

    well, in example better use ^#$, but that is not the point. I hope this answers your question.

    0 讨论(0)
  • 2021-01-13 12:00

    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 the sed alternative might be a simpler approach (it's less typing, at least).

    Edit: @Kent pointed out you have the same start and end pattern, which makes it a bit more tricky, but this should work:

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

    That basically toggles x every time it sees the pattern, and only prints when x!=0. The next in there avoids printing the pattern when it's turning printing back on.

    0 讨论(0)
  • 2021-01-13 12:07

    Is sed an alternative?

    $ sed '/#/,/#/d' input
    abd
    hfdh
    end
    
    0 讨论(0)
提交回复
热议问题