2020年08月11日

`xargs` で空白込みのパスを扱う

覚書を兼ねて。

標準入力からの内容を元に、任意のコマンドを実行できる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
posted by 天井冴太 at 12:39| Comment(0) | Information | 更新情報をチェックする
この記事へのコメント
コメントを書く
コチラをクリックしてください