我想用多行替换文件中的单行,例如,我想替换特定的函数调用,比如说,
foo(1,2)
带
if (a > 1) {
foo(1,2)
} else {
bar(1,2)
}
我怎样才能在bash中做到这一点?
答案 0 :(得分:7)
这就是sed s
命令的构建目的:
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
请注意,只有在您希望以第二行的格式化方式定义REP="${REP//\+(
)/\\n}"
时才需要REP
行。如果您刚开始使用\n
中的\t
和REP
,可能会更简单。
编辑以回应OP的问题
要更改原始文件而不创建新文件,请使用sed的--in-place
标记,如下所示:
sed --in-place "s/$ORIG/$REP/g" inputfile
请注意--in-place
标志。在运行之前进行备份,因为所有更改都是永久性的。
答案 1 :(得分:1)
ORIGINAL="foo(1,2)"
REPLACEMENT="if (a > 1) {
foo(1,2)
} else {
bar(1,2)
}"
while read line; do
if [ "$line" = "$ORIGINAL" ]; then
echo "$REPLACEMENT"
else
echo "$line"
fi
done < /path/to/your/file > /path/to/output/file
答案 2 :(得分:0)
这可能对您有用:
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
答案 3 :(得分:0)
要在文件中就地替换字符串,可以使用ed(在问题中方便地标记)。假设您的输入文件如下所示:
line before
foo(1,2)
line between
foo(1,2)
line after
您可以编写脚本来进行替换,并将其存储在script.ed
等文件中:
%s/\([[:blank:]]*\)foo(1,2)/\1if (a > 1) {\
\1 foo(1,2)\
\1} else {\
\1 bar(1,2)\
\1}/
w
q
请注意,这会考虑缩进;在原始文件中的函数调用之前,每行都有前面的空格,所以结果如下所示:
$ 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
如果函数调用本身不在一行上,但可能会被不应删除的其他字符添加,则可以将其用作替换的第一行:
%s/\([[:blank:]]*\)\(.*\)foo(1,2)/\1\2if (a > 1) {\
所以这个
} something; foo(1,2)
会变成
} something; if (a > 1) {
foo(1,2)
} else {
bar(1,2)
}
压痕仍然适当考虑。