sed:在模式匹配后对 N 行执行替换

sed: performing a replace on N lines after a pattern match

我正在尝试使用 sed 在特定模式后仅对 N 行执行替换。

查看 sed 手册页,似乎应该可以使用 addr1,+N 语法。但是我无法让它工作。

 <data>
  <variable>DebuggerItem.Count</variable>
  <value type="int">2</value>
 </data>
 <data>
  <variable>Version</variable>
  <value type="int">1</value>
 </data>

我正在执行的替换查找此标记中的数字并将它们递增 1。如下所示。

sed -r 's/([ ]*<value type=)\"(int)\"(>)([0-9]*)(.*)/echo "\"\"$((+1))"/ge' filename

我现在想将替换限制在包含 "DebuggerItem.Count" 的行之后的 N 行。在我当前的实例中,N 为 1,但我有另一个示例,我想在匹配的行之后的 5 行执行此操作,因此 N 将为 5。

它可能可以通过更复杂的替换来执行,但理想情况下我想了解更多关于使用 sed 地址的信息。

注意:我在搜索替换中的双引号遇到了一些麻烦,因为我需要对它们进行两次转义以用于以下回显。所以搜索替换有点复杂。抱歉。

我同意@Birei;不要使用 sed 执行此操作。如果在无害的地方添加换行符或重新排序节点,没有人希望您的 XML 工具中断,如果您使用基于行的工具来完成任务,那正是会发生的事情。事情会以可怕的方式崩溃,他们可能会在你忘记在那里构建的内容以及原因两个月后这样做。

有很多工具可以理智地解析和转换XML。例如,使用 xmlstarlet 你的问题可以这样解决:

xmlstarlet ed -u '//data[variable="DebuggerItem.Count"]/value' -x '. + 1' filename.xml

此处 //data[variable="DebuggerItem.Count"]/value 是一个 XPath 表达式,它选择文档中任意位置的 data 节点的 value 子节点,其 variable 子节点的值为 "DebuggerItem.Count". + 1 是另一个 XPath 表达式,表示当前节点的值加一。

另见 here

如果你执意要使用sed,放心它会反咬你一口,你可以在找到后将s命令的应用限制在三行内DebuggerItem.Count 在文件中是这样的:

#               new bit            from here it's the same as before.
#       vvvvvvvvvvvvvvvvvvvvvvvv  vvvvvvv
sed -r '/DebuggerItem\.Count/,+3 s/([ ]*<value type=)\"(int)\"(>)([0-9]*)(.*)/echo "\"\"$((+1))"/ge' foo.xml