【Linux】xargsコマンドで標準入力を引数にしてコマンドを一括実行する

目次

概要

標準入力(パイプラインなど)から渡されたデータリストを、指定したコマンドの「引数」として変換し、実行するためのコマンドです。

find コマンドで検索した大量のファイルを一括で削除したり、テキストリストを読み込んで複数のディレクトリを作成したりと、繰り返し処理を自動化するパイプライン処理の要(かなめ)となるツールです。

仕様(引数・オプション)

構文

xargs [オプション] [コマンド [引数...]]

主な引数・オプション

オプション説明
-0 / --null入力をヌル文字(\0)区切りとして扱います。ファイル名に空白が含まれる場合の誤動作を防ぎます。
-a <ファイル>標準入力の代わりに、指定したファイルを読み込んで処理します。
-d <区切り文字>入力の区切り文字を指定します(デフォルトは空白や改行)。
-I <文字列>引数を埋め込むプレースホルダーを指定します(例: {}VAR)。コマンドの途中や複数箇所に引数を配置できます。
-n <数>コマンド1回の実行につき、渡す引数の最大数を指定します。
-pコマンド実行ごとに、実行するかどうかをユーザーに問い合わせます(interactive)。
-P <数>指定したプロセス数で並列実行します(Parallel)。処理の高速化に使用されます。
-t実行されるコマンドラインを標準エラー出力に表示してから実行します(trace)。

基本の使い方

パイプで渡された文字列を、次のコマンドの引数として渡します。

コマンド

# echoで出力した3つのファイル名を、ls -l の引数として渡す
echo "file1.txt file2.txt file3.txt" | xargs ls -l

実行結果

xargs が入力を展開し、実際には ls -l file1.txt file2.txt file3.txt が実行されます。

-rw-r--r-- 1 user user 0 Jan 20 10:00 file1.txt
-rw-r--r-- 1 user user 0 Jan 20 10:00 file2.txt
-rw-r--r-- 1 user user 0 Jan 20 10:00 file3.txt

実践コマンド

安全に大量のファイルを削除する(空白ファイル対策)

ファイル名にスペースが含まれている場合、通常のパイプ処理ではスペース部分で分割されてしまいエラーになります。find -print0xargs -0 を組み合わせることで、ヌル文字区切りで安全に処理できます。

# 拡張子が .tmp のファイルを検索し、安全に削除する
find . -name "*.tmp" -print0 | xargs -0 rm -vf
removed './test file.tmp'
removed './data.tmp'

コマンドの特定の位置に引数を埋め込む(コピー・移動)

通常 xargs は引数を末尾に追加しますが、-I オプションを使うことで、コマンドの途中や特定の位置にファイル名を埋め込むことができます。

# *.jpg ファイルを backup/ ディレクトリへ一括コピーする
# "{}" の部分に入力ファイル名が置換されます
ls *.jpg | xargs -I {} cp {} ./backup/

実行前に確認を入れる(破壊的操作の防止)

rm などの危険なコマンドを実行する際、-p オプションをつけることで、実行されるコマンドラインが表示され、y を押さない限り実行されないようにします。

# ログファイルを削除する前に確認する
ls *.log | xargs -p rm
rm app.log error.log ?...y
(yを入力してEnterを押すと削除される)

ファイルからリストを読み込み、並列処理でダウンロードする

-a でリストファイルを読み込み、-P で並列プロセス数を指定します。例えば、URLリストから画像を高速にダウンロードする場合などに有効です。

# url_list.txt を読み込み、4並列で wget を実行する
xargs -a url_list.txt -P 4 -n 1 wget -q

CSVなどの区切り文字を指定して処理する

-d オプションを使うと、空白以外の文字(カンマなど)を区切り文字として認識させることができます。

# カンマ区切りの文字列をリストとして扱い、それぞれディレクトリを作成
echo -n "dir_A,dir_B,dir_C" | xargs -d "," mkdir -v
mkdir: created directory 'dir_A'
mkdir: created directory 'dir_B'
mkdir: created directory 'dir_C'

カスタムポイント

  • プレースホルダー名: -I {} が一般的ですが、-I FILENAME のように分かりやすい名前を指定することも可能です。
  • 引数の数制限: xargs は可能な限り多くの引数を一度に渡そうとしますが、コマンドによっては引数が多いとエラーになることがあります。-n 1 とすることで、入力1つにつきコマンドを1回実行するように制限できます。
  • 並列数: -P 0 を指定すると、可能な限りのプロセスを立ち上げます(CPU負荷が高まるため注意が必要です)。

注意点

  1. スペースを含むファイル名の扱い:ls | xargs rm のような書き方は、ファイル名にスペースが含まれていると「別のファイル」として認識され、意図しないファイルを削除する事故につながります。ファイル操作を行う際は、必ず find … -print0 | xargs -0 … の形式を使用してください。
  2. コマンドの長さ制限:システムには「コマンドラインの最大長(ARG_MAX)」が存在します。xargs はこれを考慮して自動的に分割実行してくれますが、極端に長い引数リストを扱う場合は挙動を理解しておく必要があります。
  3. 確認なしの実行:-p をつけないと即座に実行されます。特に rm や mv と組み合わせる場合は、一度 xargs echo などで「どのようなコマンドが生成されるか」を確認テストすることをお勧めします。

応用

Dockerの不要なリソースを一括削除する

システム上の不要なコンテナやイメージを一括で掃除する際によく使われるパターンです。

# 停止している全てのDockerコンテナIDを取得し、一括削除する
docker ps -aq | xargs -r docker rm

# <none> タグのついた古いイメージを一括削除する
docker images -f "dangling=true" -q | xargs -r docker rmi

-r (no-run-if-empty) は、入力が空の場合にコマンドを実行しないGNU拡張オプションです。

まとめ

xargsコマンドは、単なる繰り返し処理ツール以上に、Linuxのパイプラインの可能性を広げる重要なコマンドです。特に find コマンドと組み合わせたファイル操作や、-P オプションによる並列処理は、サーバー管理やデータ処理の効率を劇的に向上させます。「標準入力から受け取って、コマンドに渡す」というシンプルな役割ですが、空白文字への対策(-0)やプレースホルダー(-I)を使いこなすことで、複雑な一括処理も安全かつ高速に実行できるようになります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次