Paste code only at the beginning and end of external nested code

I have code like:

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

I want to select the inside between brackets, here is what I tried:

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

Edit:

I am trying to insert code after the first occurrence of { and until the last occurrence } .

Example:

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

I think awk is the best solution for what you really want to do:

 $ 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 //----------------- } 

Explanation:

Here is a script in a multi-line form with some explanatory comments, if you prefer it in this form, save it in a file, say nestedcode , and run it as 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" } 
+3
source

This may work for you (GNU sed):

 sed '/^void.*{$/!b;:a;/\n}$/bb;$!{N;ba};:b;s/\n/&test1&/;s/\(.*\n\)\(.*\n\)/\1test2\n\2/' file 
  • /^void.*{$/!b , if the line does not start with void and ends with { , it can be done taking into account your own needs.
  • :a;/\n}$/bb;$!{N;ba} if the line contains a newline, followed only by } , the branch to label b will otherwise be read in the next line and will refer to label a .
  • :b replacements begin here.
  • s/\n/&test1&/ after the first new line, insert the first line.
  • s/\(.*\n\)\(.*\n\)/\1test2\n\2/ after the second second line of a new line, insert the second line.
+2
source

Try this regex:

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

JavaScript example in working 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);↵//----------------↵}" 

(I know this is not a JS question, but it works to illustrate that the regex returns the desired result.)

-1
source

sed , by default, works in single lines. It can run on multiple lines with the N command to read more than one line in the pattern space.

For example, the following sed expression will connect consecutive lines in a file with @ characters between them:

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

(Example from http://www.thegeekstuff.com/2009/11/unix-sed-tutorial-multi-line-file-operation-with-6-practical-examples/ )

-1
source

All Articles