不包括来自sed / START /的第一行和最后一行,/ END /
考虑input:
=sec1= some-line some-other-line foo bar=baz =sec2= c=baz
如果我只想处理= sec1 =例如我可以通过以下方式注释该部分:
sed -e '/=sec1=/,/=[az]*=/s:^:#:' < input
差不多,差不多
这会对包括 “= sec1 =”和“= sec2 =”行的行进行注释,结果如下所示:
#=sec1= #some-line #some-other-line # #foo #bar=baz # #=sec2= c=baz
我的问题是: 什么是最简单的方法来排除开始和结束行从/ START /,/结束/范围在SED ?
我知道在很多情况下,“s :::”爪子的细化可以在这个特定情况下给出解决scheme,但是我在这里是通用解决scheme。
在“ Sed – 一个介绍和教程 ”中,Bruce Barnett写道:“稍后我会告诉你如何限制一个命令,但不包括含有指定模式的行。”但是我没有find他真正显示的地方这个。
在“ 用于SED的有用的单行脚本 ”由Eric Pement编写的时候,我只能find一个包容性的例子:
# print section of file between two regular expressions (inclusive) sed -n '/Iowa/,/Montana/p' # case sensitive
这应该做的伎俩:
sed -e '/=sec1=/,/=sec2=/ { /=sec1=/b; /=sec2=/b; s/^/#/ }' < input
这包含在sec1和sec2之间,然后用b
命令跳过第一行和最后一行。 这会在sec1和sec2(独占)之间留下所需的行,并且s
命令会添加注释符号。
不幸的是,你需要重复匹配分隔符的正则expression式。 据我所知,没有更好的方法来做到这一点。 至less你可以保持正则expression式的清洁,即使它们被使用了两次。
这是从SED FAQ改编而来:我如何处理RE1和RE2之间的所有线路,不包括线路本身?
如果你对这个范围之外的线条不感兴趣,但是只是想从这个问题(这是什么使我在这里)的问题中得到爱荷华州/蒙大拿州的非包含性的例子,你可以写下“除了第一个和最后一个匹配行“条款足够容易与第二个sed:
sed -n '/PATTERN1/,/PATTERN2/p' < input | sed '1d;$d'
就我个人而言,我发现这个比稍微更清晰(尽pipe在大文件上比较慢)
sed -n '1,/PATTERN1/d;/PATTERN2/q;p' < input
另一种方法是
sed '/begin/,/end/ { /begin/n /end/ !p }'
/begin/n
– >跳过具有“begin”模式的行
/end/ !p
– >打印所有没有“结束”模式的行
采取从布鲁斯·巴内特的sed教程http://www.grymoire.com/Unix/Sed.html#toc-uh-35a
你也可以使用awk
awk '/sec1/{f=1;print;next}f && !/sec2/{ $0="#"$0}/sec2/{f=0}1' file
我用过:
sed '/begin/,/end/{/begin\|end/!p}'
这将search模式之间的所有线,然后打印不包含模式的所有内容