覚書を兼ねて。
標準入力からの内容を元に、任意のコマンドを実行できるxargs
コマンド。例えば、以下のような使い方が出来る。
# `man xargs` で確認できる1番最初の用例より。
# /tmp以下から "core" という名前のファイルを再帰的に検索し、それを削除する。
find /tmp -name core -type f -print | xargs /bin/rm -fa
ところで、この例では、ファイル名に空白記号が含まれていた場合、上手く動作しない。空白が語と語の区切りと見做されるからである。
# 先と同じ例で、ただし対象となるファイル名が "have whitespace" であった場合。
# 期待に反してファイルは消えない。
find /tmp -name 'have whitespace' -type f -print | xargs /bin/rm -f
何故ならば、xargs
で実行する/bin/rm
は、実質的には /bin/rm -f have whitespace
となり、「have」と「whitespace」と2ファイルを消す操作となるからである。機械的に語が追加された結果、語の中の空白文字が、コマンド引数の区切り空白と見做されてしまう為である。
こういう場合どうすればいいか? 回答の1つは、xargs
への入力を明示的にクォートする事であるようだ。
# `sed` で明示的にクォートする事で、「空白を含む1語」である事を明示する。
find /tmp -name 'have whitespace' -type f -print | sed -e "s/^.*$/'&'/g" | xargs /bin/rm -f
sed
がキモい……xargs
側で面倒を見てほしい気がする……
別解としては、xargs
への入力をNULL文字区切りにする方法が在る。ただし、find
のような、NULL文字区切りで出力できるコマンドを使用する時に限られる。例えばls
では無理。
# NULL文字を区切りとして使う=空白文字は区切りと見做されない。
# `find` の `-print0` でNULL文字区切りで出力し、
# `xargs` の `-0` で、入力がNULL文字区切りである事を知らせる。
find /tmp -name 'have whitespace' -type f -print0 | xargs -0 /bin/rm -f