Вставлять код только в начале и в конце блока внешнего вложенного кода

У меня есть код, например:

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 ответа

Я думаю 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"
}

Это может работать для вас (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,
  • :b начать замены здесь.
  • s/\n/&test1&/ после первой новой строки вставьте первую строку.
  • s/\(.*\n\)\(.*\n\)/\1test2\n\2/ после 2-го от последнего символа новой строки вставьте вторую строку.

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/)

Попробуйте это регулярное выражение:

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

Пример JavaScript работы Regex:

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, но он показывает, что регулярное выражение возвращает желаемый результат.)

Другие вопросы по тегам