仅在外部嵌套代码块的开头和结尾插入代码

时间:2013-01-08 07:54:21

标签: regex linux sed awk

我有一些代码:

void main() {
//----------
  var a;
  var b;
  var c =[];
  var c = func(3);
  if (a == b) {
    print "nested";
  }    
//----------------
}

我想在括号中选择内部部分,这就是我尝试过的:

sed -re ':l;N;$!tl;N;s!(void \w+\(\) \{)([^])*!\1 Prepend;\n\2\nappend!g' test.txt

修改

我尝试在第一次出现{之后和最后一次出现}之前插入代码。

示例:

void main() { 
test1
//-----------------
  var a;
  var b;
  var c =[];
  var c = func(3);
  if (a == b) {
    print "nested";
  }
test2
//-----------------
}

4 个答案:

答案 0 :(得分:3)

我认为awk是您实际想要做的更好的解决方案:

$ awk '/{/{i++;if(i==1){print $0,"\ntest1";next}}{print}/}/{i--;if(i==1)print "test2"}' file
void main() { 
test1
//-----------------
  var a;
  var b;
  var c =[];
  var c = func(3);
  if (a == b) {
    print "nested";
  }
test2
//-----------------
}

说明:

以下是多行表单中的脚本及一些解释性注释,如果您愿意在此表单中将其保存为文件nestedcode并按awk -f nestedcode code.c运行:

BEGIN{
    #Track the nesting level 
    nestlevel=0
}
/{/ {
    #The line contained a { so increase nestlevel
    nestlevel++
    #Only add code if the nestlevel is 1
    if(nestlevel==1){
        #Print the matching line and new code on the following line
        print $0,"\ntest1"
        #Skip to next line so the next block 
        #doesn't print current line twice
        next
    }
}
{
    #Print all lines
    print
}
/}/ {
    # The line contained a } so decrease the nestlevel
    nestlevel--
    #Only print the code if the nestleve is 1
    if(nestlevel==1)
        print"test2"
}

答案 1 :(得分:2)

这可能适合你(GNU sed):

sed '/^void.*{$/!b;:a;/\n}$/bb;$!{N;ba};:b;s/\n/&test1&/;s/\(.*\n\)\(.*\n\)/\1test2\n\2/' file
  • /^void.*{$/!b如果该行不以void开头并以{结尾(这可能需要根据您自己的需要量身定制)。
  • :a;/\n}$/bb;$!{N;ba}如果该行包含换行符后跟一个},则跳转到标签b,否则在下一行读取并循环回标签a。< / LI>
  • :b在这里开始替换。
  • 在第一个换行符插入第一个字符串后,
  • s/\n/&test1&/
  • s/\(.*\n\)\(.*\n\)/\1test2\n\2/在最后一个换行符的第二个之后插入第二个字符串。

答案 2 :(得分:-1)

试试这个正则表达式:

{[^]*} // [^] = any character, including newlines.

正则表达式的JavaScript示例:

var s = "void main() {\n//----------\nvar a;\nvar b;\nvar c =[];\nvar c = func(3);\n//----------------\n}"
console.log(s.match(/{[^]*}/g));
//"{↵//----------↵var a;↵var b;↵var c =[];↵var c = func(3);↵//----------------↵}"

(我知道这不是JS问题,但它可以说明正则表达式返回所需的结果。)

答案 3 :(得分:-1)

默认情况下,

sed在单行上运行。它可以使用N命令在多行上操作,以便在模式空间中读取多行。

例如,以下sed表达式将连接文件中的连续行,并在它们之间加上@个符号:

sed -e '{
N
s/\n/ @ /
}'

(来自http://www.thegeekstuff.com/2009/11/unix-sed-tutorial-multi-line-file-operation-with-6-practical-examples/的例子)