2014-05-08 51 views
0

我有以下命令從當前目錄樹下找到並替換「OldString」和「NewString」。直接輸出sed查找並替換爲文件

sed -i 's/OldString/NewString/g' `grep -ril 'OldString' *` 

誰能告訴我如何我可能會直接的這個輸出到一個文件,用於驗證: - 然後輸出文件將顯示哪些文件進行了修改父文件+文件路徑?

例如輸出文件:

/home/htdocs/index.html 
/home/htdocs/file_containing_oldString.html 
+0

如何在$(grep -ril'OldString')中存放文件? do sed -i's .... g'$ file;完成'? – fedorqui

+0

嗨@fedorqui,你介意指導這個答案嗎? – Barney

+0

要清楚 - 「OldString」不是一個字符串,它是一個正則表達式。把它想象成一串可以/會咬你。 –

回答

3

的UNIX命令來查找文件名爲find,不grep。當他們補充說-r選項的時候,GNU的人大肆宣揚。爲了找到&替換字符串中的正則表達式是:

tmp=/usr/tmp/tmp$$ 
trap 'rm -f "$tmp"; exit' 0 
find . -type f -print | 
while IFS= read -r file 
do 
    sed 's/OldRegexp/NewString/g' "$file" > "$tmp" && 
    mv "$tmp" "$file" 
done 

與唯一需要注意的是它不會工作,如果你的文件名包含換行符 - 如果他們這樣做,然後要麼將其重命名(最好)還是看find -print0xargs -0

如果您願意,您可以通過使用sed -i明確指定tmp文件。

現在,如果你希望哪些文件被改變的列表,你可以這樣做:

tmp=/usr/tmp/tmp$$ 
trap 'rm -f "$tmp"; exit' 0 
> logfile 
find . -type f -print | 
while IFS= read -r file 
do 
    sed 's/OldRegexp/NewString/g' "$file" > "$tmp" 
    if [ $? -eq 0 -a diff -q "$tmp" "$file" ] 
    then 
     printf "%s\n" "$file" >> logfile 
     mv "$tmp" "$file" 
    fi 
done 

如果你決定使用sed -i(個人而言,我不會),然後創建TMP副本在sed之前的文件並將其用於diff。

+0

它工作正常嗎?我懷疑使用'find ... | while ...'會讓'while'塊不能訪問'$ tmp',因爲它正在打開一個新的shell。如果是這種情況(我沒有測試過),我會建議'while ... done <$(find ...)' – fedorqui

+1

循環將有權訪問變量$ tmp,它不會能夠在子外殼的上下文之外改變它。 –

+1

皇家螺絲+1。讓我拿一些餐巾紙擦拭我的屏幕上的咖啡。 –