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