#begin command block
#append all lines between two addresses to hold space
sed -n -f - <<\SCRIPT file.xml
\|<tag1>|,\|</tag1>|{ H
#at last line of search block exchange hold and pattern space
\|</tag1>|{ x
#if not conditional ; clear buffer ; branch to script end
\|<tag2>[^<]*foo[^\n]*</tag2>|!{s/.*//;h;b}
#do work ; print result; clear buffer ; close blocks
s?*?*?;p;s/.*//;h;b}}
SCRIPT
如果执行上述操作,并根据显示的数据在该行的最后一个清理行之前进行操作,则应使用如下所示的sed
模式空间:
^\n<tag1>\n<tag2>foo</tag2>\n</tag1>$
您可以随时使用l
ook 打印出模式空间。然后,您可以处理\n
字符。
sed l <file
将向您显示每一行在被调用sed
的阶段对其进行处理l
。
因此,我刚刚对其进行了测试,并且在第一行中的\backslash
后面还需要一个,comma
,但是其他方法仍然可以正常运行。在这里,我将其放在一个中,_sed_function
以便在整个答案中都可以出于演示目的方便地将其称为:(包含注释,但为简洁起见,此处将其删除)
_sed_function() { sed -n -f /dev/fd/3
} 3<<\SCRIPT <<\FILE
\|<tag1>|,\|</tag1>|{ H
\|</tag1>|{ x
\|<tag2>[^<]*foo[^\n]*</tag2>|!{s/.*//;h;b}
s?*?*?;p;s/.*//;h;b}}
#END
SCRIPT
<tag1>
<tag2>bar</tag2>
</tag1>
<tag1>
<tag2>foo</tag2>
</tag1>
FILE
_sed_function
#OUTPUT#
<tag1>
<tag2>foo</tag2>
</tag1>
现在,我们将切换p
为,l
以便在开发脚本时看到正在使用的内容,并删除非操作演示,s?
因此我们的最后一行sed 3<<\SCRIPT
如下所示:
l;s/.*//;h;b}}
然后,我将再次运行它:
_sed_function
#OUTPUT#
\n<tag1>\n <tag2>foo</tag2>\n</tag1>$
好!所以我是对的-感觉很好。现在,让我们随机播放l
一下,看看它插入但删除的行。我们将删除当前流,l
并在其中添加一个,!{block}
使其类似于:
!{l;s/.*//;h;b}
_sed_function
#OUTPUT#
\n<tag1>\n <tag2>bar</tag2>\n</tag1>$
这就是我们将其清除之前的样子。
我要向您展示的最后一件事是H
我们建立旧空间。我希望可以演示几个关键概念。因此,我l
再次删除了最后一个挂钩,并更改了第一行,以在最后添加一个窥视H
旧空间的信息:
{ H ; x ; l ; x
_sed_function
#OUTPUT#
\n<tag1>$
\n<tag1>\n <tag2>bar</tag2>$
\n<tag1>\n <tag2>bar</tag2>\n</tag1>$
\n<tag1>$
\n<tag1>\n <tag2>foo</tag2>$
\n<tag1>\n <tag2>foo</tag2>\n</tag1>$
H
旧空间可以承受线周期的影响-因此得名。所以人们经常绊倒-好吧,我经常绊倒-是它在使用后需要删除。在这种情况下,我只x
更改了一次,因此保持空间变成了模式空间,反之亦然,并且这种变化还可以承受线周期。
结果是我需要删除以前用作模式空间的保留空间。我首先使用以下命令清除当前模式空间:
s/.*//
只需选择每个字符并将其删除。我无法使用,d
因为这将结束当前的行周期,并且下一条命令将无法完成,这将严重破坏我的脚本。
h
这的工作方式H
与之类似,但是它会覆盖保留空间,因此,我只是将空白模式空间复制到了保留空间的顶部,有效地删除了它。现在我可以:
b
出来。
这就是我编写sed
脚本的方式。