やりたかったこと

findで大量のファイルを検索して、そのまま一括削除や処理をしたかった。 find . -name "*.log" | rmみたいなことをしようとしたら全然動かなくて、xargsの存在を知った。

xargsの基本的な使い方

パイプと組み合わせて引数として渡す

echo "file1.txt file2.txt file3.txt" | xargs ls -l

標準入力の内容をコマンドの引数として渡してくれる。

findと組み合わせてファイルを一括削除

find . -name "*.log" | xargs rm

findの出力をxargsがrmの引数に変換してくれる。

ファイル名にスペースがある場合は-0オプション

find . -name "*.txt" -print0 | xargs -0 rm

-print0-0を組み合わせることでスペース入りのファイル名も安全に処理できる。

一度に処理する数を制限する(-n)

echo "a b c d e" | xargs -n 2 echo
a b
c d
e

-n 2で一度に2つずつ引数を渡せる。

引数の位置を指定する(-I)

ls *.txt | xargs -I{} cp {} /backup/{}

-I{}で引数の場所を{}で指定できる。ファイルをバックアップディレクトリにコピーする時によく使った。

並列実行(-P)

find . -name "*.gz" | xargs -P 4 -I{} gzip -d {}

-P 4で4プロセス並列処理。大量のファイルを処理する時に速くなった。

ハマったポイント

  • パイプ直後にrmを書いても動かない。必ずxargsを経由する必要がある
  • ファイル名にスペースや改行が含まれる場合は-print0 | xargs -0がほぼ必須
  • -I{}を使う時は{}の前後に必要に応じてパスを指定する
  • 引数の数が多すぎると「Argument list too long」エラーが出るが、xargsを使えば回避できる
  • --dry-runオプションは存在しないので、事前にechoで確認してから本番実行する

関連記事

おすすめのVPS/ドメイン/スクール

VPSを使って本番環境を構築するなら、以下のサービスがおすすめです。