排除从SED / START /,/ END第一行和最后一行/(excluding first an

2019-06-26 21:12发布

考虑输入:

=sec1=
some-line
some-other-line

foo
bar=baz

=sec2=
c=baz

如果我想只处理=秒-1 = I例如可以注释掉的部分是:

sed -e '/=sec1=/,/=[a-z]*=/s:^:#:' < input

......嗯,差不多。

这会评论的线,包括 “=秒-1 =”和“=秒2 =”行,结果会是这样的:

#=sec1=
#some-line
#some-other-line
#
#foo
#bar=baz
#
#=sec2=
c=baz

我的问题是: 什么是排除A / START /,/ END /范围的起始和终止行在sed最简单的方法

我知道,对于“S :::”的情况很多细化的爪子可以在这个特定情况下的解决方案,但我在这里的通用的解决方案之后。

在“ 桑达-简介和教程 ”布鲁斯·巴内特写道:“我以后会告诉你如何限制命令为止,但不包括包含指定模式的行。”,但我没能找到他实际上显示这个。

在“ 有用的-LINE脚本SED由Eric Pement编译”,我只能找到包容例如:

# print section of file between two regular expressions (inclusive)
sed -n '/Iowa/,/Montana/p'             # case sensitive

Answer 1:

这应该做的伎俩:

sed -e '/=sec1=/,/=sec2=/ { /=sec1=/b; /=sec2=/b; s/^/#/ }' < input

这之间秒-1匹配和SEC2包含性,然后就跳过与第一和最后一行b命令。 这留下SEC1和秒2(不包括)之间的期望的线和s命令将注释符号。

不幸的是,你需要重复的正则表达式匹配的分隔符。 据我知道有没有更好的方式来做到这一点。 至少你可以保持正则表达式干净,即使他们使用了两次。

这是改编自SED FAQ:我如何解决所有RE1和RE2之间的界限,不包括线本身?



Answer 2:

如果你是在范围之外的行不感兴趣,而只是希望在艾奥瓦州/蒙大拿例如从问题的非包容性的变异(这是什么把我带到这里),你可以写“除了第一和最后一个匹配线”条款容易够与第二sed的:

sed -n '/PATTERN1/,/PATTERN2/p' < input | sed '1d;$d'

就个人而言,我觉得这更清楚地略(尽管速度较慢的大文件),比同等

sed -n '1,/PATTERN1/d;/PATTERN2/q;p' < input



Answer 3:

另一种方法是

sed '/begin/,/end/ {
       /begin/n
       /end/ !p
     }'

/begin/n - >跳过具有“开始”的图案的线
/end/ !p - >打印所有行没有“结束”模式

从布鲁斯·巴尼特的SED教程采取http://www.grymoire.com/Unix/Sed.html#toc-uh-35a



Answer 4:

你也可以使用AWK

awk '/sec1/{f=1;print;next}f && !/sec2/{ $0="#"$0}/sec2/{f=0}1' file


Answer 5:

我使用:

sed '/begin/,/end/{/begin\|end/!p}'

这将搜索所有的模式之间的界限,然后打印不包含该模式的一切



文章来源: excluding first and last lines from sed /START/,/END/