Replace
遞歸目錄中的快速字元串替換
如何使用帶有空格和單引號的遞歸目錄和文件名進行快速文本替換?最好使用標準 UNIX 工具,或者使用眾所周知的軟體包。
使用
find
對於許多文件來說非常慢,因為它為每個文件生成一個新程序,所以我正在尋找一種將目錄遍歷和字元串替換集成為一個操作的方法。慢搜尋:
find . -name '*.txt' -exec grep foo {} \;
快速搜尋:
grep -lr --include=*.txt foo
慢換:
find . -name '*.txt' -exec perl -i -pe 's/foo/bar/' {} \;
快速更換:
# Your suggestion here
(這個相當快,但是是兩次通過並且不處理空格。)
perl -p -i -e 's/foo/bar/g' `grep -lr --include=*.txt foo`
您只想使用:
find . -name '*.txt' -exec cmd {} \;
形式為那些
cmd
只能接受一個參數的 s。情況並非如此grep
。與grep
:find . -name '*.txt' -exec grep foo /dev/null {} +
(或
-H
與 GNU 一起使用grep
)。更多關於遞歸 grep 與 find / -type f -exec grep {} ; 哪個更高效/更快?現在進行替換,同樣的,
perl -pi
可以採用多個參數:find . -name '*.txt' -type f -exec perl -pi -e s/foo/bar/g {} +
現在這將重寫文件,無論它們是否包含
foo
。相反,您可能想要(假設 GNUgrep
和xargs
/或兼容):find . -name '*.txt' -type f -exec grep -l --null foo {} + | xargs -r0 perl -pi -e s/foo/bar/g
或者:
grep -lr --null --include='*.txt' foo . | xargs -r0 perl -pi -e s/foo/bar/g
所以只有包含的文件
foo
被重寫。順便說一句,
--include=*.txt
(--include
作為另一個 GNU 擴展)是一個 shell glob,所以應該被引用。例如,如果--include=foo.txt
在目前目錄中有一個文件被呼叫,shell 會--include=*.txt
在呼叫grep
. 如果沒有,對於許多 shell,您會收到關於 glob 無法匹配任何文件的錯誤。所以你想要
grep --include='*.txt'