从行首替换为多个模式之一到另一行末尾替换为第二个模式

从行首替换为多个模式之一到另一行末尾替换为第二个模式

我有一个这样的文件:

data data data
$globaltext blah gibberjabber
somemorestuff etc
);
data data data
$otherjunk yada gibberish
etc etc
more etc
);

我想要的结果是这个文件:

data data data
/*$globaltext blah gibberjabber
somemorestuff etc
);*/
data data data
/*$otherjunk yada gibberish
etc etc
more etc
);*/

我知道如何使用 for 循环来做到这一点sed,但我想要一个 1 行sed命令来实现这一点,比如:

sed '/blah\|yada/s/^\(\$.*)\;\)/\/\*\1\*\//' filename

开头的模式匹配将搜索限制为 1 行,因此显然上面的命令失败了。但这个概念正是我想要的:

  1. 匹配模式列表中的任何一个 (blahyada),
  2. 然后将所需的文本 ( /*) 添加到匹配行的开头,
  3. 并将其他所需文本 ( */) 添加到匹配不同模式 ( ) 的下一行的末尾);,其中 2 个匹配之间的行数不同(并不总是相隔 2 行等)

这是可能的还是我应该使用 for 循环或更好的方法?

主要是要求学习,因为我是 shell 脚本新手。

答案1

sed   -e's|^\$|/*&|;t$' -eb -e:$      -e'### handle top end of loop' \
      -e's|);$|&*/|;t'  -en -eb$      -e'### handle the bottom end'

data data data
/*$globaltext blah gibberjabber
somemorestuff etc
);*/
data data data
/*$otherjunk yada gibberish
etc etc
more etc
);*/

两次尝试的s///替换均已t生效。在第一种情况下,如果替换成功,sed不是最终b脱离脚本并分支到:$标签。当它不成功时,它不会跳转branch 命令,因此它只是分支并自动打印输入,直到^\$匹配为止。

一旦匹配,它就会进入一个从 at 开始:$并结束于 at 的闭环,因此在循环完成之前b$它不会再次尝试第一次替换。s///在循环的这一端,sed t估计);$成功s///替换的匹配情况,一旦成功,它就会从脚本中分支出来,使用下一个输入行(如果有)从头开始重新启动循环。在它执行之前,它将递归地自动打印,然后用每次迭代的 ext 输入行覆盖模式空间n- 因此它永远不会不必要地缓冲。

相关内容