打印所有内容使用awk除了匹配范围模式

时间:2013-04-11 16:24:34

标签: awk range design-patterns

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

e.g。

$ cat 1.t

abd
hfdh
#  
fafa
deafa
123 
#
end

我想要的结果:

cat 1.t

abd
hfdh
end

编辑:

我举了一个不好的例子。 endpattern应该与startpattern不同,因为我还没有测试过。那是我的错。

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

3 个答案:

答案 0 :(得分:7)

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

完全相同

我猜您的寻找方式与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'
是的,与sed的相似。

如果开始和结束真的相同,你想用awk做,你需要标记。

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

嗯,在示例中更好地使用^#$,但这不是重点。我希望这能回答你的问题。

答案 1 :(得分:1)

是替代品吗?

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

答案 2 :(得分: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避免在重新打印时打印图案。