2011-08-31 45 views
0

这是我的shell脚本的一部分,我用它在工作目录中执行递归查找和替换。备份和其他实用程序在其他功能,这是与我的问题无关。Sed和grep正则表达式的语法不同

#!/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 \(。该模式对于sed是正确的,但对于grep不适用。 正则表达式语法为grepsed不同。我能做什么?

回答

0

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

(有时也可作为egrep

而且,为什么不继续使用发现?

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

还要注意-i选项sed,它允许在文件就地改变和除去bufferFile/CHOWN/MV逻辑。

+0

我没有得到错误信息,但包含的文件'$这个 - >报告(“富”)'不发现并因此被替换。我也尝试用'([^)] *)'替换'(。*)',但是无效。 – Dagguh

+0

我不知道我明白'$ this ...'的问题。也许美元在某个地方被bash解释了? – cadrian

+1

感谢'-i'国旗,它减少了我的一些代码:) – Dagguh

0

为什么不比较源并覆盖源文件之前缓存文件:

#!/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" 
+0

对不起,这不是问题。 – Dagguh