使用awk打印除匹配范围图案之外的所有内容
在Awk中,范围模式不是表达式,因此不能使用“!”来表示它。 那么如何实现它(使用awk打印除匹配范围模式之外的所有内容) e、 g $cat 1.t使用awk打印除匹配范围图案之外的所有内容,awk,range,design-patterns,Awk,Range,Design Patterns,在Awk中,范围模式不是表达式,因此不能使用“!”来表示它。 那么如何实现它(使用awk打印除匹配范围模式之外的所有内容) e、 g $cat 1.t abd hfdh # fafa deafa 123 # end 我想要的结果是: 类别1.t abd hfdh end 编辑: 我举了一个无礼的例子。endpattern应该与startpattern不同,因为我还没有测试它。那是我的错 同时,我想以不同的方式操作范围模式和非范围模式。所以sed不是我的选择。sed是一种选择吗 $ se
abd
hfdh
#
fafa
deafa
123
#
end
我想要的结果是:
类别1.t
abd
hfdh
end
编辑:
我举了一个无礼的例子。endpattern应该与startpattern不同,因为我还没有测试它。那是我的错
同时,我想以不同的方式操作范围模式和非范围模式。所以sed不是我的选择。sed是一种选择吗
$ sed '/#/,/#/d' input
abd
hfdh
end
如果您真的需要使用
awk
,类似的方法应该可以:
awk 'BEGIN{x=1} /startpattern/{x=0} /endpattern/{x=1;next} x{print}'
awk 'BEGIN{x=1} /pattern/{x=!x;next} x{print}'
尽管sed
替代方法可能更简单(至少打字更少)
编辑:@Kent指出,你有相同的开始和结束模式,这使它有点棘手,但这应该是可行的:
awk 'BEGIN{x=1} /startpattern/{x=0} /endpattern/{x=1;next} x{print}'
awk 'BEGIN{x=1} /pattern/{x=!x;next} x{print}'
它基本上在每次看到模式时切换
x
,并且仅在x=0
。那里的下一个
避免了在重新打开打印时打印图案。您刚才给出了一个棘手的(我不知道该称之为好还是坏^ ^ ^)示例。您的文本具有完全相同的startpattern
和endpattern
(#
)
我猜您正在寻找与sed'/#/,/#/d'
或sed-n'/#/,/#/,相同的方法!p'
awk中有一些类似的地址模型(与sed的地址模型不同)。手册页中有说明。我说的不一样,你的例子很好。如果start==end
awk的地址模型不起作用:
kent$ echo "abd
hfdh
#
fafa
deafa
123
#
end"|awk '/#/,/#/{next}1'
abd
hfdh
fafa
deafa
123
end
因为awk匹配同一行(再次检查手册页),但如果它们不同,请参见此示例:
kent$ echo "abd
hfdh
#
fafa
deafa
123
##
end"|awk '/#/,/##/{next}1'
abd
hfdh
end
它会给你想要的。如果是这样的话,你可以:
awk '/start/,/end/{next}1'
是的,和塞德的非常相似
如果开始和结束真的是一样的,你想用awk来做,你需要标志
kent$ echo "abd
hfdh
#
fafa
deafa
123
#
end"|awk '/#/&&!f{f=1;next}f&&/#/{f=0;next}!f'
abd
hfdh
end
在这个例子中,最好使用
^#$
,但这不是重点。我希望这能回答您的问题。这对OP的示例不起作用,它有相同的开始和结束模式。您不仅需要检查x
是否打印,还需要检查x
本身的设置。@Kent捕捉得好。。。在考虑到这一点的替代版本中进行编辑。+1用于您棘手的示例文本<代码>awk'/start/,/end/{next}1'我的问题的正确和详细的答案,尽管我没有用这个尴尬的例子清楚地解释它!