Che*_*evy 44 unix scripting sed text-manipulation
考虑输入:
=sec1=
some-line
some-other-line
foo
bar=baz
=sec2=
c=baz
Run Code Online (Sandbox Code Playgroud)
如果我只想处理= sec1 =我可以通过以下方式注释掉该部分:
sed -e '/=sec1=/,/=[a-z]*=/s:^:#:' < input
Run Code Online (Sandbox Code Playgroud)
......好吧,差不多.
这将注释包括 "= sec1 ="和"= sec2 ="行的行,结果将类似于:
#=sec1=
#some-line
#some-other-line
#
#foo
#bar=baz
#
#=sec2=
c=baz
Run Code Online (Sandbox Code Playgroud)
我的问题是:在sed中从/ START /,/ END /范围中排除开始和结束行的最简单方法是什么?
我知道在很多情况下,"s :::"爪子的细化可以在这种特定情况下给出解决方案,但我在这里遵循通用解决方案.
在" Sed - An Introduction and Tutorial "中,Bruce Barnett写道:"我稍后会告诉你如何限制命令,但不包括包含指定模式的行."但是我无法找到他实际显示的位置这个.
在由Eric Pement编写的" 有用的SED单行文章"中,我只能找到包容性的例子:
# print section of file between two regular expressions (inclusive)
sed -n '/Iowa/,/Montana/p' # case sensitive
Run Code Online (Sandbox Code Playgroud)
Vil*_*ari 38
这应该做的伎俩:
sed -e '/=sec1=/,/=sec2=/ { /=sec1=/b; /=sec2=/b; s/^/#/ }' < input
Run Code Online (Sandbox Code Playgroud)
这包含在sec1和sec2之间,然后用b命令跳过第一行和最后一行.这将在sec1和sec2之间留下所需的行(不包括),并且该s命令会添加注释符号.
不幸的是,您需要重复使用正则表达式来匹配分隔符.据我所知,没有比这更好的方法了.至少你可以保持正则表达式清洁,即使它们被使用了两次.
这是根据SED FAQ改编的:如何处理RE1和RE2之间的所有线路,不包括线路本身?
Pau*_*ker 13
如果你对范围之外的线路不感兴趣,但只是想从问题(这就是我带到这里)的爱荷华州/蒙大拿州的非包容性变体,你可以写"除了第一个和最后一个匹配行"子句很容易与第二个sed:
sed -n '/PATTERN1/,/PATTERN2/p' < input | sed '1d;$d'
就个人而言,我发现这比同等的更清晰(虽然在大文件上比较慢)
sed -n '1,/PATTERN1/d;/PATTERN2/q;p' < input
另一种方式是
sed '/begin/,/end/ {
/begin/n
/end/ !p
}'
Run Code Online (Sandbox Code Playgroud)
/begin/n- >跳过具有"开始"模式的行
/end/ !p- >打印所有没有"结束"模式的行
取自Bruce Barnett的sed教程http://www.grymoire.com/Unix/Sed.html#toc-uh-35a