我已經改變了我的董事結構,我要做到以下幾點:遞歸查找和替換基於正則表達式
- 執行遞歸grep來找到比賽的所有實例
- 切換到更新的位置串
一個例子(出數以百計的)是:
from common.utils import debug --> from etc.common.utils import debug
要獲得LL的什麼我正在尋找我做的實例:
$ grep -r 'common.' ./
不過,我也需要確保common
是前面有一個空格。我將如何做這個查找和替換?
我已經改變了我的董事結構,我要做到以下幾點:遞歸查找和替換基於正則表達式
一個例子(出數以百計的)是:
from common.utils import debug --> from etc.common.utils import debug
要獲得LL的什麼我正在尋找我做的實例:
$ grep -r 'common.' ./
不過,我也需要確保common
是前面有一個空格。我將如何做這個查找和替換?
很難準確地告訴你想要什麼,因爲重構示例更改了導入以及包,但以下內容將更改爲common. -> etc.common.
目錄中的所有文件:
sed -i 's/\bcommon\./etc.&/' $(egrep -lr '\bcommon\.' .)
這假定你有gnu sed可用,大多數linux系統都可以。此外,只是爲了讓你知道,如果sed要處理的文件太多,這將會失敗。在這種情況下,你可以這樣做:
egrep -lr '\bcommon\.' . | xargs sed -i 's/\bcommon\./etc.&/'
注意,這可能是一個好主意,因爲sed -i'.OLD' 's/\bcommon\./etc.&/'
運行sed命令,讓你得到的原始文件的備份。
感謝您指出,這是一個錯字。 – David542
這大致上是你如何使用find來做到的。這就要求測試
find . -name \*.java -exec sed "s/FIND_STR/REPLACE_STR/g" {}
這意味着作爲「從當前目錄開始發現,在.java結尾的所有文件和文件執行SED(其中{}是一個佔位符爲當前找到的文件)」 S/FIND_STR/REPLACE_STR/g「在當前文件的每行中用REPLACE_STR替換FIND_STR
爲什麼你有'1,$'? sed *已經*在'1,$'上運行。 –
vi習慣的力量。我刪除它。 –
如果您grep
實現支持Perl語法(-P
標誌上,例如Linux的它通常用),你可以從附加功能中受益,如文字界限:
$ grep -Pr '\bcommon\.'
順便說一句:
grep -r
往往比之前管道式的find
命令慢得多,如Rob的例子。此外,當你確定發現的文件的名稱不包含任何空格,使用xargs
比-exec
快得多:
$ find . -type f -name '*.java' | xargs grep -P '\bcommon\.'
或者,適用於Tim的例子:
$ find . -type f -name '*.java' | xargs sed -i.bak 's/\<common\./etc.common./'
注意在後面的例子中,替換是在爲每個更改的文件創建一個* .bak備份後完成的。這樣,您就可以查看該命令的結果,然後刪除備份:
$ find . -type f -name '*.bak' | xargs rm
如果你已經做了一個oopsie,下面的命令將恢復到以前的版本:
$ find . -type f -name '*.bak' | while read LINE; do mv -f $LINE `basename $LINE`; done
當然,如果你不知道文件名和路徑中是否有空白,則應通過find
的-exec
參數應用命令。
乾杯!
egrep是Solaris命令afaikr。 –
@RobKielty'egrep'是至少所有的GNU系統,簡稱'grep的-E'(擴展的正則表達式,你其實並不需要在這裏) – Kevin
此外,OP,你想'\ .',而不僅僅是一個' .';否則它被解釋爲除了換行符之外的任何內容。 – Kevin