Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

add a line between matching pattern - unix

Tags:

sed

awk

I want to insert "123" below madguy-xyz- line in "module xyz". There are multiple modules having similar lines. But i want to add it in only "module xyz".

module abc 
    njkenjkfvsfd
    madguy-xyz-mafdvnskjfvn
    enfvjkesn
endmodule

module xyz
    njkenjkfvsfd
    madguy-xyz-mafdvnskjfvn
    enfvjkesn
endmodule

This is the code i tried but doesn't work,

sed -i "/module xyz/,/^endmodule/{/madguy-xyz-/a 123}" <file_name>

This is the error I got: sed: -e expression #1, char 0: unmatched `{'

like image 710
MS_007 Avatar asked Dec 09 '22 23:12

MS_007


2 Answers

This might work for you (GNU sed):

sed '/module xyz/{:a;n;/madguy-xyz-/!ba;p;s/\S.*/123/}' file

For a line containing module xyz, continue printing lines until one containing madguy-xyz-.

Print this line too and then replace it with 123.

Another alternative solution:

sed '/module/h;G;/madguy-xyz.*\nmodule xyz/{P;s/\S.*/123/};P;d' file

Store any module line in the hold space.

Append the module line to each line.

If the first line contains madguy-xyz- and the second module xyz, print the first then substitute the second for 123.

Print the first line and delete the whole.

like image 177
potong Avatar answered Dec 12 '22 11:12

potong


With your shown samples, please try following.

awk '1; /^endmodule$/{found=""};/^module xyz$/{found=1} found && /^ +madguy-xyz-/{print "123"} ' Input_file

Once you are happy with results of above command, to save output into Input_file itself try following then:

awk '1;/^endmodule$/{found=""} /^module xyz$/{found=1} found && /^ +madguy-xyz-/{print "123"} ' Input_file > temp && mv temp Input_file

Explanation: Adding detailed explanation for above.

awk '                      ##Starting awk program from here.
1;
/^endmodule$/{found=""}    ##Printing current line here.
/^module xyz$/{            ##Checking condition if line contains module xyz then do following.
  found=1                  ##Setting found to 1 here.
}
found && /^ +madguy-xyz-/{   ##Checking if found is SET and line contains madguy-xyz- then do following.
  print "123"              ##Printing 123 here.
}
' Input_file               ##Mentioning Input_file name here.

NOTE: In case your line exactly having module xyz value then change above /module xyz/ (this condition) to $0=="module xyz" too.

like image 30
RavinderSingh13 Avatar answered Dec 12 '22 11:12

RavinderSingh13