私の一般的な方法の1つは、特定のタイプのすべてのファイルに対してgrepsを実行することです。たとえば、「rumpus」という単語が含まれているすべてのHTMLファイルを見つけます。それをするために、私は使用します
find /path/to -name "*.html" | xargs grep -l "rumpus"
場合によっては、find
はmy new file.html
などの名前にスペースが含まれるファイルを返します。 xargs
がこれをgrep
に渡すと、次のエラーが発生します。
grep: /path/to/bad/file/my: No such file or directory
grep: new: No such file or directory
grep: file.html: No such file or directory
私はここで何が起こっているかを見ることができます:パイプまたはxargs
はスペースをファイル間の区切り文字として扱います。けれども、私の生活の中で、私はこのふるまいを防ぐ方法を理解することができません。 find
+ xargs
で実行できますか?または、まったく異なるコマンドを使用する必要がありますか?
使用する
find ... -print0 | xargs -0 ...
例えば.
find /path/to -name "*.html" -print0 | xargs -0 grep -l "rumpus"
findのmanページから
-print0
True; print the full file name on the standard output, followed
by a null character (instead of the newline character that
‘-print’ uses). This allows file names that contain newlines or
other types of white space to be correctly interpreted by pro-
grams that process the find output. This option corresponds to
the ‘-0’ option of xargs.
findはコマンド自体を実行できるため、xargsを使用する必要はありません。これを行う場合、シェルが名前の文字を解釈することを心配する必要はありません。
find /path/to -name "*.html" -exec grep -l "rumpus" '{}' +
findのmanページから
-execコマンド{} +
-execアクションのこのバリアントは、選択されたファイルに対して指定されたコマンドを実行しますが、コマンドラインは、選択された各ファイル名を末尾に追加することによって構築されます。コマンドの呼び出しの総数は、一致したファイルの数よりもはるかに少なくなります。コマンドラインは、xargsがコマンドラインをビルドするのとほぼ同じ方法でビルドされます。コマンド内では、 `{} 'のインスタンスを1つだけ使用できます。コマンドは、開始ディレクトリで実行されます。
システムのfindおよびxargバージョンが-print0
および-0
スイッチをサポートしていない場合(たとえば、AIXのfindおよびxargs)、これを使用できます。
find /your/path -name "*.html" | sed 's/ /\\ /g' | xargs grep -l "rumpus"
ここで、sedはxargsのスペースをエスケープします。