2011-08-31 31 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