sed or awk script problem

Hi All

I am having a file as shown below

File1#

modyle 1 {
test jsj
hhsjh 13e3 
jsjjs 

}

memP(dbg_trace) {
ajjs
jsjs
jsjs

Test(claer) {
jsjs
}
TestStep ( RunTime ) {
RUN jksj
Controller (ddd) {
akk sns
sjsj
}
Controller (ddssd) {
akk sns
sjsj
}
Controller (ddssssd) {
akk sns
sjsj
}
}
}


modyless 2 {
test jsj
hhsjh 13e3 
jsjjs 

}


memP(dbg66_trace) {
ajjs
jsjs
jsjs

Test(claer) {
jsjs
}
TestStep ( RunTime ) {
RUN jksj
Controller (ddssd) {
akkss snss
sjssj
}
Controller (ddssssd) {
aksk snss
sssjsj
}
Controller (ssddssssd) {
askk ssns
ssjssj
}
}
}

modyless 3 {
test jsj
hhsjh 13e3 
jsjjs 

}

I am having another file as shown below

File 2 #

TestStep(RunExtra) {
      RunMode : RunTProg;
      Controller(WBP0) {
        ComparesGOID : On;
        ComparesGo : On;
          }
}

Now I want to insert File2 content in the File1 content
with a pattern match , Pattern match is complex

First we should match "memP" in File1 then it should check the last bracket "}" in memP wrapper and then insert the File Content "File2" before that "}"

Output File should be like this

File3 :

modyle 1 {
test jsj
hhsjh 13e3 
jsjjs 

}

memP(dbg_trace) {
ajjs
jsjs
jsjs

Test(claer) {
jsjs
}
TestStep ( RunTime ) {
RUN jksj
Controller (ddd) {
akk sns
sjsj
}
Controller (ddssd) {
akk sns
sjsj
}
Controller (ddssssd) {
akk sns
sjsj
}
}

TestStep(RunExtra) {
      RunMode : RunTProg;
      Controller(WBP0) {
        ComparesGOID : On;
        ComparesGo : On;
          }
}

}


modyless 2 {
test jsj
hhsjh 13e3 
jsjjs 

}


memP(dbg66_trace) {
ajjs
jsjs
jsjs

Test(claer) {
jsjs
}
TestStep ( RunTime ) {
RUN jksj
Controller (ddssd) {
akkss snss
sjssj
}
Controller (ddssssd) {
aksk snss
sssjsj
}
Controller (ssddssssd) {
askk ssns
ssjssj
}
}
TestStep(RunExtra) {
      RunMode : RunTProg;
      Controller(WBP0) {
        ComparesGOID : On;
        ComparesGo : On;
          }
}



}

modyless 3 {
test jsj
hhsjh 13e3 
jsjjs 

}

Colored one is new content which is being put

I tried below script
sed '/memP/ r File2' File1 > output.txt
But it is not selecting the last bracket in the memP wrapper

Please provide me your valuable suggestions

How about

awk '
FNR == NR       {INS=INS DL $0
                 DL = ORS
                 next
                }
/^memP/         {C = 1
                }
C               {BRACNT += gsub (/{/, "&") - gsub (/}/, "&")
                }
C && !BRACNT    {print INS
                 C = 0
                }
1
' file2 file1
1 Like
awk '{if (/memP/) { start=1}
if (start == 1) { if (/\{/) {count=count+1}
if (/\}/) {count=count-1}
if (count== 0) {  while ((getline line < "file2") > 0){print line}start=0;close("file2")}
}
print }' file1

Hi Rudic

Thanks a lot ! Its working fine
could you help me out by giving a small explanation of this working code?

Thanks
Kshitij

Hi RudiC in below code.

awk '
FNR == NR       {INS=INS DL $0
                 DL = ORS
                 next
                }
/^memP/         {C = 1
                }
C               {BRACNT += gsub (/{/, "&") - gsub (/}/, "&")
                }
C && !BRACNT    {print INS
                 C = 0
                }
1
' file2 file1

Kindly explain the highlighted part. Why you need to assign DL with ORS separately.?
and what substraction value would we get from

gsub (/{/, "&") - gsub (/}/, "&")

Thanks

awk '
FNR == NR       {INS=INS DL $0          # variable to be inserted is being populated with the first file's lines seperated by
                 DL = ORS               # delimiter DL which is empty on first occurrence and set to ORS (= "\n") here 
                 next
                }
/^memP/         {C = 1                  # search pattern: start of region of interest; C = 1 means: collect braces
                }
C               {BRACNT += gsub (/{/, "&") - gsub (/}/, "&")    # substitute opening and closing braces by themselves, add/subtr. count
                }                                               # gsub accounts for multiple braces in one line; BRACNT = level of braces
C && !BRACNT    {print INS              # if we're in the region AND the brace count is zero: last closing braces encountered, print INS
                 C = 0                  # out of region
                }
1                                       # default action: print current line (i.e. closing brace from last action)
' file2 file1
1 Like

Rudic There is a sudden change of my requirement
Can you provide your valuable comments

My output file should look like this

modyle 1 {
test jsj
hhsjh 13e3 
jsjjs 

}

memP(dbg_trace) {
ajjs
jsjs
jsjs

Test(claer) {
jsjs
}
TestStep ( RunTime ) {
RUN jksj
Controller (ddd) {
akk sns
sjsj
}
Controller (ddssd) {
akk sns
sjsj
}
Controller (ddssssd) {
akk sns
sjsj
}
}

TestStep(RunExtra) {
      RunMode : RunTProg;
    Controller(ddd) {
        ComparesGOID : On;
        ComparesGo : On;
          }

      Controller(ddssd) {
        ComparesGOID : On;
        ComparesGo : On;
          }
Controller(ddssssd) {
        ComparesGOID : On;
        ComparesGo : On;
          }



}

}


modyless 2 {
test jsj
hhsjh 13e3 
jsjjs 

}


memP(dbg66_trace) {
ajjs
jsjs
jsjs

Test(claer) {
jsjs
}
TestStep ( RunTime ) {
RUN jksj
Controller (ddssd) {
akkss snss
sjssj
}
Controller (ddssssd) {
aksk snss
sssjsj
}
Controller (ssddssssd) {
askk ssns
ssjssj
}
}
TestStep(RunExtra) {
      RunMode : RunTProg;
      Controller(ddssd) {
        ComparesGOID : On;
        ComparesGo : On;
          }
 Controller(ddssssd) {
        ComparesGOID : On;
        ComparesGo : On;
          }

Controller(ssddssssd) {
        ComparesGOID : On;
        ComparesGo : On;
          }


}



}

modyless 3 {
test jsj
hhsjh 13e3 
jsjjs 

}


The problem here it should read the controller in each Teststep and edit the Teststep of file2 so that controller of that teststep should be copied in the output file

Basically , It should match the memP and match the last "}" of the memP wrapper and insert the File2 by modifying it but insert the controller wrappers of the current TestStep wrapper

Try

awk '
FNR == NR       {if (/^ *Contr/) C = 1
                 if (/}/) next
                 if (C) CON = CON ORS $0
                 else INS = INS ORS $0
                 next
                }
/^memP/         {M = N = 1

                }
M               {BRACNT += gsub (/{/, "&") - gsub (/}/, "&")
                 if (/^ *Contr/)  CTR[N++] = $2
                }
M && !BRACNT    {print INS
                 for (i=1; i<N; i++)    {sub (/\([^)]*\)/, CTR, CON)
                                         print CON
                                         print "}"
                                        }
                 print "}"
                 M = 0
                }
1
' file2 file1 
modyle 1 {
test jsj
hhsjh 13e3
jsjjs
 
}

memP(dbg_trace) {
ajjs
jsjs
jsjs   

Test(claer) {
jsjs
}
TestStep ( RunTime ) {
RUN jksj
Controller (ddd) {
akk sns
sjsj
}
Controller (ddssd) {
akk sns
sjsj
}
Controller (ddssssd) {  
akk sns
sjsj
}
}

TestStep(RunExtra) {
      RunMode : RunTProg;
 
      Controller(ddd) {
        ComparesGOID : On;
        ComparesGo : On;
}

      Controller(ddssd) {
        ComparesGOID : On;
        ComparesGo : On;
}

      Controller(ddssssd) {
        ComparesGOID : On;
        ComparesGo : On;
}   
}
}

 
modyless 2 {
test jsj
hhsjh 13e3 
jsjjs 

}
.
.
.

Correction of formatting issues is left to the reader.