参考SO上的其他Q / As,我将以下内容添加到我的.bashrc中:
function findandreplace {
find . -type f -name "$1" -not -path "*/.git/*" -print0 | xargs -0 sed -i 's/$2/$3/g'
}
奇怪的是,它没有做任何事情。当我将其更改为:
function findandreplace {
echo "find . -type f -name \"$1\" -not -path \"*/.git/*\" -print0 | xargs -0 sed -i 's/$2/$3/g'"
}
我得到了
$ findandreplace "*.cpp" "A.cpp" "B.cpp"
find . -type f -name "*.cpp" -not -path "*/.git/*" -print0 | xargs -0 sed -i 's/A.cpp/B.cpp/g'
正如所料。复制粘贴该命令然后执行预期的操作。
我的初始功能出了什么问题?
答案 0 :(得分:4)
's/$2/$3/g'
部分没有意义;单引号可防止参数扩展,因此您的实际sed脚本为s/$2/$3/g
(美元符号和全部)而不是s/A.cpp/B.cpp/g
。由于正则表达式中的$
表示“字符串结束”(或有时称为“行尾”),$2
将永远不会匹配任何内容。
要解决此问题,您可以改为使用双引号:
function findandreplace {
find . -type f -name "$1" -not -path "*/.git/*" -print0 \
| xargs -0 sed -i "s/$2/$3/g"
}
请注意,如果$2
或$3
包含斜杠,则会出现这种情况。 (已编辑添加:)要解决此问题,您可以要求Bash在这些参数中将/
替换为\/
,但这非常难看:
function findandreplace {
find . -type f -name "$1" -not -path "*/.git/*" -print0 \
| xargs -0 sed -i "s/${2//\//\/}/${3//\//\/}/g"
}
答案 1 :(得分:2)
由于使用单引号:
sed -i 's/$2/$3/g'
将无效,因为shell不会扩展这些变量。像这样使用sed:
sed -i "s/$2/$3/g"