I want to replace a single line in a file with multiple lines, e.g., I want to replace a particular function call, say,
foo(1,2)
with
if (a > 1) {
foo(1,2)
} else {
bar(1,2)
}
How can I do it in bash?
I want to replace a single line in a file with multiple lines, e.g., I want to replace a particular function call, say,
foo(1,2)
with
if (a > 1) {
foo(1,2)
} else {
bar(1,2)
}
How can I do it in bash?
This is what the sed s
command was built for:
shopt -s extglob
ORIG="foo(1,2)"
REP="if (a > 1) {
foo(1,2)
} else {
bar(1,2)
}"
REP="${REP//+(
)/\\n}"
sed "s/$ORIG/$REP/g" inputfile > outputfile
Note that the REP="${REP//\+( )/\\n}"
lines are only needed if you want to define the REP
in the formatted way that I did on line two. It might be simpler if you just used \n
and \t
in REP
to begin with.
Edit: Note! You need to escape '
and \
as well in your REP if you have them.
Edit in response to the OP's question
To change your original file without creating a new file, use sed's --in-place
flag, like so:
sed --in-place "s/$ORIG/$REP/g" inputfile
Please be careful with the --in-place
flag. Make backups before you run it because all changes will be permanent.
shopt -s extglob
is required and the backslash before the plus sign needs to be removed. –
Nikitanikki REP="${REP//+( )/\\n}"
–
Chris sed: -e expression #1, char 320: unknown option to `s'
–
Delano This might work for you:
cat <<\! |
> a
> foo(1,2)
> b
> foo(1,2)
> c
> !
> sed '/foo(1,2)/c\
> if (a > 1) {\
> foo(1,2)\
> } else {\
> bar(1,2)\
> }'
a
if (a > 1) {
foo(1,2)
} else {
bar(1,2)
}
b
if (a > 1) {
foo(1,2)
} else {
bar(1,2)
}
c
To replace strings in-place in a file, you can use ed (as conveniently tagged in the question). Assuming your input file looks like this:
line before
foo(1,2)
line between
foo(1,2)
line after
You can write a script to do the substitution and store it in a file such as script.ed
:
%s/\([[:blank:]]*\)foo(1,2)/\1if (a > 1) {\
\1 foo(1,2)\
\1} else {\
\1 bar(1,2)\
\1}/
w
q
Notice that this takes indentation into account; every line is prepended with whatever blanks were there before the function call in the original file, so the result would look like this:
$ ed -s infile < script.ed
$ cat infile
line before
if (a > 1) {
foo(1,2)
} else {
bar(1,2)
}
line between
if (a > 1) {
foo(1,2)
} else {
bar(1,2)
}
line after
Should the function call not be on a line on its own but potentially prepended by other characters that shouldn't be removed, you could use this as the first line of the substitution:
%s/\([[:blank:]]*\)\(.*\)foo(1,2)/\1\2if (a > 1) {\
So this
} something; foo(1,2)
would become
} something; if (a > 1) {
foo(1,2)
} else {
bar(1,2)
}
with indentation still properly accounted for.
© 2022 - 2024 — McMap. All rights reserved.