5

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

例如

$猫 1.t

abd
hfdh
#  
fafa
deafa
123 
#
end

我想要的结果:

猫 1.t

abd
hfdh
end

编辑:

我举了一个不恰当的例子。endpattern 应该与 startpattern 不同,因为我还没有对此进行测试。那是我的错。

同时,我想以不同的方式操作范围模式和非范围模式。所以 sed 不是我的选择。

4

3 回答 3

7

你只是给出了一个棘手的(我不知道我应该称之为好还是坏^_^)的例子。startpattern您的文字与endpattern( #)完全相同

我猜你正在寻找与sed '/#/,/#/d'或相同的方式sed -n '/#/,/#/!p'

awk 中有一些类似(与 sed 不同)的地址模型。在手册页中有解释。我说不一样,你的例子很好。如果start == endawk 的地址模型不起作用:

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'

是的,与 sed 的非常相似。

如果 start 和 end 真的相同,你想用 awk 来做,你需要 flag。

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

好吧,例如更好地使用^#$,但这不是重点。我希望这回答了你的问题。

于 2013-04-11T17:26:53.227 回答
1

sed 是替代品吗?

$ sed '/#/,/#/d' input
abd
hfdh
end
于 2013-04-11T16:39:41.410 回答
1

如果你真的需要使用awk,这样的事情应该可以工作:

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

尽管sed替代方案可能是一种更简单的方法(至少打字更少)。

编辑:@Kent 指出你有相同的开始和结束模式,这使得它有点棘手,但这应该工作:

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

基本上x每次看到模式时都会切换,并且仅在x!=0. 当next它重新打开打印时,那里避免打印图案。

于 2013-04-11T16:56:17.513 回答