简体   繁体   English

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

[英]sed: performing a replace on N lines after a pattern match

I'm trying to use sed to perform a replace on only N lines after a specific pattern. 我正在尝试使用sed在特定模式后仅在N行上执行替换。

Looking at the sed man page it seems like it should be possible to do using addr1,+N syntax. 查看sed手册页,似乎应该可以使用addr1,+ N语法进行操作。 But I can not get it to work. 但是我无法使其正常工作。

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

The replace I am performing finds the numbers in this markup and increments them by 1. It is as follows. 我正在执行的替换在此标记中找到数字并将其递增1。如下。

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

I now want to restrict that replacement to just the N lines after the one containing "DebuggerItem.Count". 我现在想将替换限制为仅包含“ DebuggerItem.Count”的那一行之后的N行。 In my current instance N is 1, but I have another example where I would want to perform this for 5 lines after the matched one, so N would be 5. 在当前实例中,N为1,但还有另一个示例,我想在匹配的那一行之后执行5行,因此N为5。

It can probably be performed with a more complex replace, but ideally I would like to learn more about using addresses with sed. 它可能可以通过更复杂的替换来执行,但理想情况下,我想了解有关使用sed地址的更多信息。

Note: I had some trouble with the double quotes in the search replace as I needed to double escape them for the following echo. 注意:我在搜索替换中的双引号时遇到了一些麻烦,因为我需要为以后的回声对它们进行双转义。 So the search replace is a little convoluted. 因此搜索替换有些复杂。 My apologies. 我很抱歉。

I agree with @Birei; 我同意@Birei; don't do this with sed . 不要用sed这么做。 Nobody expects your XML tools to break if there's a newline added in a harmless place or nodes reordered, and that's exactly the sort of thing that will happen if you use line-based tools for the task. 如果在无害的位置添加了换行符或对节点进行了重新排序,没人会期望您的XML工具会损坏,而这正是您使用基于行的工具完成任务时发生的事情。 Things would break in horrible ways, and they will probably do it two months after you forgot what you built there and why. 事情将以可怕的方式破裂,在您忘记在那里建造什么以及为什么建造两个月后,事情可能会发生。

There are plenty of tools that can parse and transform XML sanely. 有很多工具可以明智地解析和转换XML。 For example, with xmlstarlet your problem can be solved like this: 例如,使用xmlstarlet您的问题可以这样解决:

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

Here //data[variable="DebuggerItem.Count"]/value is an XPath expression selecting the value subnode of a data node anywhere in the document whose variable subnode has a value of "DebuggerItem.Count" , and . + 1 //data[variable="DebuggerItem.Count"]/value是一个XPath表达式,用于选择文档中variable子节点的值为"DebuggerItem.Count"和的data节点的value子节点. + 1 . + 1 is another XPath expression meaning the value of the current node plus one. . + 1是另一个XPath表达式,表示当前节点的值加1。

See also here . 另请参阅此处

If you are hell-bent on using sed , and rest assured that it will come back to bite you, you can restrict the application of your s command to three lines after you found DebuggerItem.Count in the file like this: 如果您热衷于使用sed ,并且放心它会再次咬住您,则可以在文件中找到DebuggerItem.Count之后将s命令的应用限制为三行:

#               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\\"\2\\"\3$((\4+1))\5"/ge' foo.xml

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM