在Awk中,范围模式不是表达式,因此canot使用“!”不是吗 那么如何实现它(使用awk打印所有内容除了匹配范围模式)?
e.g。
$ cat 1.t
abd
hfdh
#
fafa
deafa
123
#
end
我想要的结果:
cat 1.t
abd
hfdh
end
我举了一个不好的例子。 endpattern应该与startpattern不同,因为我还没有测试过。那是我的错。
同时,我想以不同的方式操作范围模式和非范围模式。所以sed不是我的选择。
答案 0 :(得分:7)
你只是给了一个棘手的(我不知道我应该称之为好还是坏^ _ ^)的例子。您的文字与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'
是的,与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
避免在重新打印时打印图案。