Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Printing all contents EXCEPT matching range pattern using awk

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)?

e.g.

$cat 1.t

abd
hfdh
#  
fafa
deafa
123 
#
end

the result I wanted:

cat 1.t

abd
hfdh
end

EDIT:

I gave an impertinent example. the endpattern should be different with the startpattern because I just have not test this. That's My fault.

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

like image 826
Zhilong Jia Avatar asked Apr 11 '13 16:04

Zhilong Jia


People also ask

Can we search a pattern using awk?

In awk, regular expressions (regex) allow for dynamic and complex pattern definitions. You're not limited to searching for simple strings but also patterns within patterns.

What is pattern matching in awk?

Any awk expression is valid as an awk pattern. The pattern matches if the expression's value is nonzero (if a number) or non-null (if a string). The expression is reevaluated each time the rule is tested against a new input record.

How do I print a line between two patterns in shell script?

The sed command will, by default, print the pattern space at the end of each cycle. However, in this example, we only want to ask sed to print the lines we need. Therefore, we've used the -n option to prevent the sed command from printing the pattern space. Instead, we'll control the output using the p command.


2 Answers

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.

like image 82
Kent Avatar answered Sep 27 '22 23:09

Kent


Is sed an alternative?

$ sed '/#/,/#/d' input
abd
hfdh
end
like image 29
Fredrik Pihl Avatar answered Sep 27 '22 22:09

Fredrik Pihl