我得到了一些看起来像这样的代码:
lots of code...
start(){
some code...
if mountpart "$1" /mnt -w ; then
some code...
}
lots of code...
我现在想在if mountpart "$1" /mnt -w ; then
之后使用sed
插入一些新代码。
由于if mountpart "$1" /mnt -w ; then
存在多次,因此我无法在每次匹配后简单地附加新代码。它应该只在start() { }
为此使用sed
是个好主意吗?或者执行此类更改的适当工具是什么?
答案 0 :(得分:2)
一旦你需要开始跟踪状态(例如,我在文件中的哪个位置?到目前为止我看到了什么?),我通常会从sed切换到perl。这是一个简单的单行程序来完成你需要的工作(用你需要插入的新代码替换“NEW CODE”;用实际文件替换<filename>
):
perl -ne 'BEGIN{$state=0} print; if (/^\s*start\(\){/) {$state++;} if (/if mountpart "\$1" \/mnt -w ; then/) { if ($state==1) {print "NEW CODE\n"; $state++;} }' <filename>
简要地说明这一点:-n
使perl的工作有点像sed;它将读取每一行并处理它,但是,除非你要求它,否则它不会打印该行;这让我们在输出新代码之前输出每一行。 -e
使perl从命令行读取程序。接受程序并重新格式化并添加注释,我们得到了这个:
// -n runs the program for every line of input
// but a BEGIN {} block only runs once, before input
BEGIN {
//where are we in the input?
// 0=no start() yet
// 1=start() was seen
// 2=we have output the new code; never do it again
$state=0
}
print; // print the line we just read in, unchanged
if (/^\s*start\(\){/) { //regex. Did we see start(){ ?
$state++; //if so, change to next state
}
if (/if mountpart "\$1" \/mnt -w ; then/) { //regex. did we see mountpart cmd?
if ($state==1) { //if so, are we in the right state
print "NEW CODE\n"; //if so, output the new code
$state++; //...and change to next state
//...so we don't output new code 2x
}
}
请注意,我们从不按名称引用该行...我们只是说“print”来打印该行,并且正则表达式看起来像sed paterns,我们假设我们匹配该行。那是因为-n
将每一行读入perl的$_
变量,这是print等函数的默认参数。这不是我写一个大型perl程序的方式,但对于像这样的单行或简单的一次性修复脚本来说是合适的(和惯用的)。
你也可以省略<filename>
并像sed那样输入输入,例如:
cat myfile.txt | perl -ne 'BEGIN...'
答案 1 :(得分:1)
我的sed脚本,patch.sed:
# replace your "if then" block inside start() by another pattern
# to make it unrecognizable to sed in the next command
/^start(){/,/^}/!{s/if mountpart "$1" \/mnt -w ; then/outside_start/g}
# inside start(), append "NEW CODE" after "if then" block
/if mountpart "$1" \/mnt -w ; then/a\
NEW CODE
# recover your "if then" block outside start()
/^start(){/,/^}/!{s/outside_start/if mountpart "$1" \/mnt -w ; then/g}
输入:
lots of code...
if mountpart "$1" /mnt -w ; then
lots of code
start(){
some code...
if mountpart "$1" /mnt -w ; then
some code...
}
lots of code...
if mountpart "$1" /mnt -w ; then
运行它:
sed -f patch.sed input
输出:
lots of code...
if mountpart "$1" /mnt -w ; then
lots of code
start(){
some code...
if mountpart "$1" /mnt -w ; then
NEW CODE
some code...
}
lots of code...
if mountpart "$1" /mnt -w ; then
你的“start(){”应该在一行的开头,“}”也与它匹配。这是在start()内匹配的方式;
如果没有脚本,您可以使用“-e”选项通过sed执行多重编辑。但要小心逃避$。
答案 2 :(得分:1)
这可能对您有用:
sed '/^start()/,/^}/!b;x;/./{x;b};x;/if mountpart "$1" \/mnt -w ; then/!b;h;a\ NEWCODE' file
如果有很多NEWCODE
,请将其放在一个文件中并改为运行:
sed '/^start()/,/^}/!b;x;/./{x;b};x;/if mountpart "$1" \/mnt -w ; then/!b;h;r newcode.txt' file
说明:
保留空间是备用寄存器。它可用于操作文本或(如本例中)标记/开关以显示已发生的事件。
start()
和}
之间拯救/^start()/,/^}/!b
x;/./{x;b}
x;/if mountpart "$1" \/mnt -w ; then/!b
h
NEWCODE
a\ NEWCODE
或r newcode.txt
答案 3 :(得分:0)
TXR:
@(collect)
@prolog
@(until)
start(){
@(end)
@(collect)
@inner
@(until)
if mountpart "$1" /mnt -w ; then
@(end)
@(collect)
@epilog
@(end)
@(output)
@{prolog "\n"}
@{inner "\n"}
@{epilog[0]}
NEW TEXT
@{epilog[1..t] "\n"}
@(end)
数据:
lots of code...
if mountpart "$1" /mnt -w ; then
lots of code
start(){
some code...
if mountpart "$1" /mnt -w ; then
some code...
}
lots of code...
if mountpart "$1" /mnt -w ; then
执行命令
$ txr insert.txr code.sh
lots of code...
if mountpart "$1" /mnt -w ; then
lots of code
start(){
some code...
if mountpart "$1" /mnt -w ; then
NEW TEXT
some code...
}
lots of code...
if mountpart "$1" /mnt -w ; then