xargs
シェル

10万個のファイルを削除するコマンド

ファイル名が00000から99999の連番になっている10万個のファイルがあるとします。
(10万個のファイルを生成する方法はこちら

$ ls | wc -l
  100000

まず、普通にrm *とやろうとすると、

$ rm *
-bash: /bin/rm: Argument list too long

となってできません。
なぜかというと、rm *はシェルの引数展開で、rm 00000 00001 00002 00003 ...という感じで展開されるのですが、引数として与えられる文字数には上限があるので、それに引っかかってしまうからです。

引数の最大長はgetconf ARG_MAXで調べられるようです。
macOSの場合は262144のようでした。

$ getconf ARG_MAX
262144

仮に5文字の10万個のファイル名を引数展開したとすると、区切り文字1文字を足して (5 + 1) * 100000 = 600000 なので、262144を大幅に上回ることになります。

それでは、10万個のファイルを削除するにはどうしたらよいでしょうか。
xargsというコマンドを使うといいようです。

$ ls | xargs rm

これでめでたく10万個のファイルが消えてくれました。

ただし、今回は00000, 00001, 00002, 00003, ....., 99999のようにファイル名に区切り文字が含まれていないことが期待できたからこれでよかったのですが、ファイル名に区切り文字(スペース)が含まれている場合は、これだと失敗します。

$ touch 'aaa bbb.txt'
$ ls | xargs rm
rm: aaa: No such file or directory
rm: bbb.txt: No such file or directory

その場合、findコマンドで区切り文字を\0(ヌル文字)としてファイルのリストを出力してxargsコマンドに渡せばよいようです。
xargsコマンドもヌル文字を区切り文字として処理するように、-0オプションをつけて実行します。

$ find . -type f -print0 | xargs -0 rm

おしまい。