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

Tod*_*ly' 3 linux sed

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

...
fast
     n : abstaining from food
Run Code Online (Sandbox Code Playgroud)

我想要替换它的价值是:

...
Noun
 : abstaining from food
Run Code Online (Sandbox Code Playgroud)

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

sed '/fast/,/^     n : / s/fast/Noun/'
Run Code Online (Sandbox Code Playgroud)

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

Pau*_*ce. 5

试试这个:

sed "h; :b; \$b ; N; /^${1}\n     n/ {h;x;s//Noun\n/; bb}; \$b ; P; D"
Run Code Online (Sandbox Code Playgroud)

不幸的是,保罗的回答是读取整个文件,其中使您可能想要做的任何其他处理变得困难.此版本成对读取行.

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

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

sed 'h; :b; $b ; N; /^'${1}'\n     n/ {h;x;s//Noun\n/; bb}; $b ; P; D'
#   ?open        close?    ?open                                close?
Run Code Online (Sandbox Code Playgroud)

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