Sed 和 grep 正则表达式语法不同
这是我的 shell 脚本的一部分,我用它在工作目录中执行递归查找和替换。备份和其他实用程序位于其他功能中,与我的问题无关。
#!/bin/bash
# backup function goes here
# @param $1 The find pattern.
# @param $2 The replace pattern.
function findAndReplace {
bufferFile=/tmp/tmp.$$
filesToReplace=`find . -type f | grep -vi cvs | grep -v '#'`
sedPattern="s/$1/$2/g"
echo "Using pattern $sedPattern"
for f in $filesToReplace; do
echo "sedding file $f"
sed "$sedPattern" "$f" > "$bufferFile"
exitCode=$?
if [ $exitCode -ne 0 ] ; then
echo "sed $sedPattern exited with $exitCode"
exit 1
fi
chown --reference=$f $bufferFile
mv $bufferFile $f
done
}
backup
findAndReplace "$1" "$2"
以下是示例用法:recursive-replace.sh "function _report" "function report"
。
它有效,但有一个问题。它对工作目录中的所有文件使用sed。我只想 sed 那些包含查找模式的文件。
然后,我将行:修改
filesToReplace=`find . -type f | grep -vi cvs | grep -v '#'`
为:
filesToReplace=`grep -rl "$1" . | grep -vi cvs | grep -v '#'`
它也有效,但不适用于所有查找模式。例如,对于模式 \$this->report\((.*)\)
我收到错误: grep: Unmatched ( or \(
)。此模式对于 < em>sed,但不适用于grep。 grep 和 sed 的正则表达式语法不同。我能做些什么?
This is a part of my shell script, which I use to perform a recursive find and replace in the working directory. Backup and other utilities are in other functions, which are irrelevant to my problem.
#!/bin/bash
# backup function goes here
# @param $1 The find pattern.
# @param $2 The replace pattern.
function findAndReplace {
bufferFile=/tmp/tmp.$
filesToReplace=`find . -type f | grep -vi cvs | grep -v '#'`
sedPattern="s/$1/$2/g"
echo "Using pattern $sedPattern"
for f in $filesToReplace; do
echo "sedding file $f"
sed "$sedPattern" "$f" > "$bufferFile"
exitCode=$?
if [ $exitCode -ne 0 ] ; then
echo "sed $sedPattern exited with $exitCode"
exit 1
fi
chown --reference=$f $bufferFile
mv $bufferFile $f
done
}
backup
findAndReplace "$1" "$2"
Here's a sample usage: recursive-replace.sh "function _report" "function report"
.
It works, but there is one problem. It uses sed on ALL files in the working directory. I would like to sed only those files, which contain the find pattern.
Then, I modified the line:
filesToReplace=`find . -type f | grep -vi cvs | grep -v '#'`
to:
filesToReplace=`grep -rl "$1" . | grep -vi cvs | grep -v '#'`
And it works too, but not for all find patterns. E.g. for pattern \$this->report\((.*)\)
I recieve error: grep: Unmatched ( or \(
. This pattern is correct for sed, but not for grep.
Regex syntaxes for grep and sed differ. What can I do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用 grep -E(“扩展”正则表达式选项)——它通常可以解决问题。
(有时也可用作
egrep
)另外,为什么不继续使用 find 呢?
另请注意
sed
的-i
选项,它允许就地更改文件并删除 bufferFile/chown/mv 逻辑。use
grep -E
("extended" regexp option) — it usually solves the problem.(also sometimes available as
egrep
)Also, why not keep using find?
Also note the
-i
option ofsed
, which allows in-place changes in files and the removal of the bufferFile/chown/mv logic.为什么不在覆盖源文件之前比较源文件和缓冲区文件:
Why not compare source and buffer files before overwriting the source file: