2013-04-11 57 views
4

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

例如

$猫1.T

abd 
hfdh 
# 
fafa 
deafa 
123 
# 
end 

我想要的结果:

猫1.T

abd 
hfdh 
end 

编辑:

我给了一个不恰当的例子。 endpattern应该与startpattern不同,因为我只是没有测试过这个。这是我的错。

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

+1

+1为您的棘手示例文本! – Kent 2013-04-11 17:32:49

回答

6

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

我猜你是为sed '/#/,/#/d'sed -n '/#/,/#/!p'

寻找同样的方式有一些similiar(不一样的sed的)地址AWK模型。在手册页中有解释。我说的不一样,你的榜样是好的。如果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' 

是的,和sed的很相似。

如果开始和结束真的是一样的,你想用awk做,你需要标志。

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

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

+0

+1对于很好的解释 – 2013-04-11 17:38:53

+0

'awk'/ start /,/ end/{next} 1''正确和详细的答案为我的问题,但我没有解释清楚使用这个尴尬的例子! – 2013-04-12 04:18:25

0

是sed的替代方案吗?

$ sed '/#/,/#/d' input 
abd 
hfdh 
end 
0

如果你确实需要使用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可以避免在重新打印时打印图案。

+0

这不适用于OP的例子,它有相同的开始和结束模式。您需要检查'x'不仅用于打印,还用于设置'x'本身。 – Kent 2013-04-11 17:32:01

+0

@Kent good catch ...在考虑到这一点的替代版本中编辑。 – twalberg 2013-04-11 18:17:58