find で空白を含んだパスに検索を実行し、結果を xargs に渡す

find で空白を含んだパスに対して検索を実行し、その結果を xargs に渡しても思うような結果が得られない。どうしてかというと、xargs は標準入力から空白または改行で区切られた文字列群を読み込むから。パスに含まれた空白が xargs に区切り文字として解釈されてしまう。

% ls "Foo Bar"
hoge1.txt  hoge2.txt

% find "Foo Bar" -name "*.txt" | xargs grep "Hello"
grep: Foo: No such file or directory            # "Foo" で一つ目の入力として捉えられている
grep: Bar/hoge1.txt: No such file or directory  # "Bar/hoge1.txt" で二つ目の入力として捉えられている
grep: Foo: No such file or directory
grep: Bar/hoge2.txt: No such file or directory

こういう場合には、find のオプションに -print0 をつけ、xargs のオプションに -0 を付けるとうまくいく。find の -print0 は各ファイル名にヌル文字を付加するオプション。xargs の -0 は、文字列の区切りに、空白ではなくヌル文字を使うようにするオプション。

% find "Foo Bar" -name "*.txt" -print0 | xargs -0 grep "Hello"
Foo Bar/hoge1.txt:Hello world!

というか、空白を含んだディレクトリを作らんといてー。