Sed 和 grep 正则表达式语法不同

发布于 2024-12-02 07:23:32 字数 1327 浏览 0 评论 0原文

这是我的 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,但不适用于grepgrepsed 的正则表达式语法不同。我能做些什么?

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烦人精 2024-12-09 07:23:32

使用 grep -E(“扩展”正则表达式选项)——它通常可以解决问题。

(有时也可用作 egrep

另外,为什么不继续使用 find 呢?

filesToReplace=`find . -name CVS -prune -o -type f -exec grep -l "$1" {} \; | grep -v '#'`

另请注意 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?

filesToReplace=`find . -name CVS -prune -o -type f -exec grep -l "$1" {} \; | grep -v '#'`

Also note the -i option of sed, which allows in-place changes in files and the removal of the bufferFile/chown/mv logic.

夢归不見 2024-12-09 07:23:32

为什么不在覆盖源文件之前比较源文件和缓冲区文件:

    #!/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
            cmp -s $f $bufferFile
            if [ $? -ne 0 ]; then
                chown --reference=$f $bufferFile
                mv $bufferFile $f
            fi
        done
    }

backup
findAndReplace "$1" "$2"

Why not compare source and buffer files before overwriting the source file:

    #!/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
            cmp -s $f $bufferFile
            if [ $? -ne 0 ]; then
                chown --reference=$f $bufferFile
                mv $bufferFile $f
            fi
        done
    }

backup
findAndReplace "$1" "$2"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文