sed:查找两行以上的模式,而不是在该模式之后替换

时间:2009-10-16 09:23:00

标签: linux sed

哇,这个人真的抓住了我。我想在这里需要一些棘手的sed技能。这是我试图替换的命令文本的输出值:

...
fast
     n : abstaining from food

我想用它替换它的值是:

...
Noun
 : abstaining from food

事实证明这是我认为的诡计。因为'fast'被列出了很多次,因为它列在行的开头的其他地方。所以我想出了这个来定义范围:

sed '/fast/,/^     n : / s/fast/Noun/'

我认为会这样做,但是......不幸的是,这并没有结束替换,并且此次匹配后的其余输出被Noun取代。比赛结束后如何让sed停止更换?更好的是,我可以找到两行模式匹配并替换它吗?

3 个答案:

答案 0 :(得分:5)

试试这个:

sed "h; :b; \$b ; N; /^${1}\n     n/ {h;x;s//Noun\n/; bb}; \$b ; P; D"

不幸的是,保罗的答案会读取整个文件,在该文件中,您可能需要进行任何其他处理。此版本成对读取行。

通过将sed脚本括在双引号而不是单引号中,可以包含shell变量,例如位置参数。我建议用花括号围绕它们,以便它们与相邻的字符分开。当使用双引号时,你必须要小心想要进行各种扩展的shell。在这个例子中,我已经转义了美元符号,表示分支命令的输入文件的最后一行。否则,shell将尝试替换可能为null的变量$b的值,从而使sed不满意。

另一种技术是使用单引号,每次有shell变量时关闭并打开它们:

sed 'h; :b; $b ; N; /^'${1}'\n     n/ {h;x;s//Noun\n/; bb}; $b ; P; D'
#   ↑open        close↑    ↑open                                close↑

我假设您的预期结果中的“[/ code]”是拼写错误。如果不是,请告诉我。

答案 1 :(得分:1)

这似乎可以做你想要的:

sed -e ':a;N;$!ba;s/fast\n     n/Noun\n/'

我基本上从here偷了答案。

答案 2 :(得分:0)

这可能对您有用:

sed '$!N;s/^fast\n\s*n :/Noun\n :/;P;D' file
...
Noun
 : abstaining from food