使用awk打印除匹配范围图案之外的所有内容

使用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

在Awk中,范围模式不是表达式,因此不能使用“!”来表示它。 那么如何实现它(使用awk打印除匹配范围模式之外的所有内容)

e、 g

$cat 1.t

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'我的问题的正确和详细的答案,尽管我没有用这个尴尬的例子清楚地解释它!