我有一个这样的文件:
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 行,因此显然上面的命令失败了。但这个概念正是我想要的:
- 匹配模式列表中的任何一个 (
blah
或yada
), - 然后将所需的文本 (
/*
) 添加到匹配行的开头, - 并将其他所需文本 (
*/
) 添加到匹配不同模式 ( ) 的下一行的末尾);
,其中 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
脱离脚本并分支到:$
标签。当它不成功时,它不会跳转b
ranch 命令,因此它只是分支并自动打印输入,直到^\$
匹配为止。
一旦匹配,它就会进入一个从 at 开始:$
并结束于 at 的闭环,因此在循环完成之前b$
它不会再次尝试第一次替换。s///
在循环的这一端,sed
t
估计);$
成功s///
替换的匹配情况,一旦成功,它就会从脚本中分支出来,使用下一个输入行(如果有)从头开始重新启动循环。在它执行之前,它将递归地自动打印,然后用每次迭代的 ext 输入行覆盖模式空间n
- 因此它永远不会不必要地缓冲。