Trying to print a string using sed after a line/statement as below,
class name extends #(p val1 = 10,
p val2 = 20,
p val3 = 30) f_name;
" class " and " extends " and " ; " at the end of that line/statement (ie, consuming multiple lines) will remain constant, rest of the other terms are random.
Expected Result:
class name extends #(p val1 = 10,
p val2 = 20,
p val3 = 30) f_name;
string t;
Trial done as below,
Trial_command:
sed -i '/^class/a\\string t;'
Trial_Result:
class name extends #(p val1 = 10,
string t;
p val2 = 20,
p val3 = 30) f_name;
The above command works proper if the class statement ends in the same line as below
class name extends f_name;
But not working when its consumes multiple lines.
Please suggest on this.
Multiline techniques must be used. With GNU sed
:
sed -E '/^\s*class\s+\w+\s+extends\b/{ :a; /;\s*$/!{N; ba}; s/$/\nstring t;/ }' file
perl -lpe '$class=1 if /^class/; if ($class and /;$/) { $_ .= "\nstring t;"; $class = 0 }` file
The above command remembers when a line starting with class
is seen. Then adds a line string t;
and forgets that class
is seen, when it sees a line ending with ;
.
See https://perldoc.perl.org/perlrun.html for help on various options used.
Ed can do this.
#!/bin/sh
cat >> append.ed << EOF
\$
a
string t;
.
wq
EOF
ed -s filename < append.ed
rm -v ./append.ed
With GNU sed for -z
(to read the whole input as a single string) and for \n
to mean newline in the replacement text:
$ sed -z 's/class name extends[^;]*;/&\n\nstring t;/' file
class name extends #(p val1 = 10,
p val2 = 20,
p val3 = 30) f_name;
string t;
otherwise using any awk in any shell on every UNIX box:
$ awk '
{ r = (NR>1 ? r ORS : "") $0 }
END { sub(/class name extends[^;]*;/,"&\n\nstring t;",r); print r }
' file
class name extends #(p val1 = 10,
p val2 = 20,
p val3 = 30) f_name;
string t;
This perl one-liner does the job:
perl -0777 -ape 's/\bclass \w+ extends[\s\S]+?;\K/\nstring t;/' file
class name extends #(p val1 = 10,
p val2 = 20,
p val3 = 30) f_name;
string t;
Explanation:
s/ # substitute
\b # word boundary
class # literally
\w+ # 1 or more word characters (class name)
extends # literally
[\s\S]+? # 1 or more any character including newline
; # semi colon
\K # forget all we have seen until this position
/ # with
\n # linefeed
string t; # literally
/ # end subs
This might work for you (GNU sed):
sed '/^class/!b;:a;/;$/!{N;ba};/extends/astring t;' file
If the current line does not begin class
, not interested.
If the current line does not end ;
, append the next line and repeat.
If the current line(s) contains extended
, append another line string t;
.
If a blank line then a line containing string t;
is required, either:
sed '/^class/!b;:a;/;$/!{N;ba};/extends/G;//astring t;' file
or:
sed '/^class/!b;:a;/;$/!{N;ba};/extends/a\\nstring t;' file
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.