どうやって作れますか?早くテキスト変えるそして再帰的ディレクトリとファイル名スペースそしてアポストロフィ?標準の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
(これは非常に高速ですが、2回のパスが必要で、スペースを処理しません。)
perl -p -i -e 's/foo/bar/g' `grep -lr --include=*.txt foo`
ベストアンサー1
あなたはちょうど次を使用したいと思います:
find . -name '*.txt' -exec cmd {} \;
cmd
1 つの引数のみを受け入れる 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
書き換えられます。
ところで、別のGNU拡張はシェルグローブなので、引用する必要があります--include=*.txt
。--include
たとえば、--include=foo.txt
呼び出されている現在のディレクトリにファイルがある場合、シェルは呼び出す--include=*.txt
前にそのファイルに展開されますgrep
。それ以外の場合、多くのシェルでは、globがファイルと一致しないというエラーが発生します。
だからあなたは欲しいでしょうgrep --include='*.txt'