【xargsコマンド早見表】find/grep連携・引数受け渡しと並列実行(-P)の実務パターン15選

コマンドリファレンス

こんにちは、Bash玄(ばっしゅげん)です。

Linuxサーバーの運用やシェルスクリプト開発で、「find で検索した大量のファイルをまとめて削除したい」「grep でヒットしたファイル群を別ディレクトリへ一括コピーしたい」「大量の画像変換やAPIリクエストを並列実行して一気に終わらせたい」という場面は多いはずです。

しかし、初心者の方がよくつまずくのが「パイプ(|)で次のコマンドに渡したのに動かない」という問題です。rmcpmvchmodkill などの多くのLinuxコマンドは、標準入力ではなく「コマンドライン引数」としてファイル名やPIDを受け取る設計になっているため、パイプで直接渡しても無視されるかエラーになってしまいます。

そこで必須となるのが xargs コマンドです。xargs標準入力から受け取った文字列を整形し、別コマンドの引数として渡して実行するための超強力なツールです。

この記事では、xargs の基本構文から主要オプション早見表、さらに実務で即コピペして使える15の実践パターン(find/grep連携、空白対策、並列実行 -P、プレースホルダー -I など)とよくある落とし穴まで徹底解説します。

  1. 1. 最短で動かす基本構文
    1. 1.1 基本構文
    2. 1.2 引数が多すぎるエラー(Argument list too long)を解決する仕組み
  2. 2. xargs 主要オプション一覧・早見表
  3. 3. 実務で使える頻出パターン集(コピペ実例15選)
    1. 3.1 find × xargs によるスペースを含むファイルの一括安全処理
    2. 3.2 大量画像のダウンロード・変換を並列実行して時間短縮(-P)
    3. 3.3 grepで見つかったファイル群をまとめて別のディレクトリへコピーする
    4. 3.4 gitの不要なマージ済みローカルブランチを一括削除する
    5. 3.5 プレースホルダー(-I)を使って引数の位置を自由に配置する
    6. 3.6 -n オプションで引数を分割してバッチ処理する
    7. 3.7 カンマや改行区切りのテキストを安全に処理する(-d)
    8. 3.8 パイプ不要!ファイルから直接引数を読み込む(-a)
    9. 3.9 実行されるコマンドを画面に表示して確認する(-t)
    10. 3.10 本番環境での誤操作防止!実行前に対話確認する(-p)
    11. 3.11 空入力での誤動作を防ぐ(-r / –no-run-if-empty)
    12. 3.12 複数ファイルの内容を sed / awk で一括置換・集計する
    13. 3.13 特定プロセスのPIDを抽出して一括killする
    14. 3.14 大量ファイルのパーミッション・所有者を一括変更する
    15. 3.15 検索結果をまとめて tar アーカイブに圧縮・バックアップする
  4. 4. よくあるエラー・落とし穴と対処法
    1. 4.1 ファイル名の「空白割れ」バグと -0 対策
    2. 4.2 -I オプションを使うと暗黙的に「1行ずつ実行」になる仕様
    3. 4.3 並列実行時(-P)のログ出力混ざり対策
    4. 4.4 シェル組み込みコマンドや関数が呼べない問題
  5. 5. まとめ & 関連記事
    1. 関連コマンド・リンク
  6. 関連記事

1. 最短で動かす基本構文

まずは xargs の最もシンプルな基本構文と、なぜこのコマンドが重要なのか(パイプとの違い・制限回避の仕組み)を押さえましょう。

1.1 基本構文

# 基本構文:標準入力を受け取ってコマンドの引数に渡す
コマンド1 | xargs [オプション] コマンド2 [初期引数]

例えば、テキストファイルに書かれたファイル名一覧をまとめて削除したい場合、以下のように実行します。

# ファイル一覧(list.txt)に記載されたファイルをまとめて削除
cat list.txt | xargs rm

# 直接ファイルから読み込む場合(推奨:パイプ不要)
xargs -a list.txt rm

cat list.txt | rm と実行しても rm は標準入力を読み込まないため何も削除されませんが、xargs を挟むことで rm file1.txt file2.txt ... という形で引数として展開され、正常に実行されます。

1.2 引数が多すぎるエラー(Argument list too long)を解決する仕組み

大量のファイル(数万〜数十万件)を一括処理しようとして rm /var/log/*.log のようにワイルドカードを実行すると、以下のエラーが発生することがあります。

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

これは、Linuxカーネルに「1回のコマンド実行に渡せる引数と環境変数の合計サイズの上限(ARG_MAX / 通常2MB〜数MB程度)」が定められているためです。シェルが一気にすべてのファイル名を展開してしまうと、この上限を超えて実行不能になります。

xargs は、このシステム上限(ARG_MAX)を自動的に認識し、引数が上限を超えないよう適切なサイズに自動分割して複数回に分けてコマンドを実行してくれます。そのため、何百万件もの大量ファイルであっても安全かつ確実に一括処理できます。

2. xargs 主要オプション一覧・早見表

実務で頻出する xargs の主要オプションを一覧表にまとめました。迷ったときはこの早見表を参照してください。

オプション ロングオプション 機能・役割 実用ワンライナー例
-I {} --replace={} 置換文字列(プレースホルダー)を指定し引数の配置位置を自由に変更 xargs -I {} mv {} {}.bak
-0 --null 入力データをヌル文字(\0)区切りとして解釈(空白・改行割れ対策) find . -name "*.txt" -print0 | xargs -0 rm
-P N --max-procs=N 最大N個のプロセスを並列実行(0を指定すると上限なしで並列化) xargs -P 4 -I {} curl -O {}
-n N --max-args=N 1回のコマンド実行に渡す引数の最大数をN個に制限 xargs -n 2 echo
-d c --delimiter=c 入力データの区切り文字を指定(改行 \n やカンマ , など) xargs -d '\n' rm
-r --no-run-if-empty 標準入力が空(空白のみ)の場合、コマンドを実行しない(GNU拡張・安全対策) find . -name "*.tmp" | xargs -r rm
-t --verbose 実際に実行されるコマンドを標準エラー出力に表示(トレース確認) cat list.txt | xargs -t rm
-p --interactive コマンド実行前に確認プロンプト(?...)を表示し対話式で実行 cat list.txt | xargs -p rm
-L N --max-lines=N 最大N行の入力を1回のコマンド実行に渡す xargs -L 1 ./process.sh
-a file --arg-file=file 標準入力の代わりに指定ファイルから引数を直接読み込む xargs -a servers.txt ssh

3. 実務で使える頻出パターン集(コピペ実例15選)

ここからは、インフラ運用や日々の業務自動化で即座に役立つ15の実践パターンをコード例付きで解説します。

3.1 find × xargs によるスペースを含むファイルの一括安全処理

実務で最も使われる黄金の組み合わせです。ファイル名にスペース(半角空白)や改行、日本語が含まれている場合、通常の xargs では空白で別々の引数として分割(空白割れ)され、予期せぬファイルを削除・移動してしまう大事故に繋がります。

これを完全に防ぐには、find-print0xargs-0(ヌル文字区切り)を必ずセットで併用します。

# スペースを含むファイル(例: "My Document 2026.log")も安全に一括削除
find /var/log/app -name "*.log" -mtime +30 -print0 | xargs -0 -r rm

# 空白を含むファイルを一括でバックアップディレクトリへ移動
find . -maxdepth 1 -name "*.bak" -print0 | xargs -0 -I {} mv {} /backup/

find コマンドの詳しい使い方・オプション早見表 も合わせて確認してください。

3.2 大量画像のダウンロード・変換を並列実行して時間短縮(-P)

-P N オプションを使うと、CPUコア数やネットワーク帯域を活用して最大N個のプロセスを並列(マルチプロセス)実行できます。直列処理では数十分かかる処理を数分に短縮できます。

# URL一覧ファイル(urls.txt)から4並列でファイルを一括ダウンロード
cat urls.txt | xargs -P 4 -n 1 curl -O -s

# ディレクトリ内のPNG画像を8並列でWebP形式に一括変換(cwebp利用)
find ./images -name "*.png" -print0 | xargs -0 -P 8 -I {} sh -c 'cwebp "$1" -o "${1%.png}.webp"' _ {}

-P 0 を指定すると「システムが許す限り無制限に並列化」されますが、CPUやメモリを枯渇させる危険があるため、通常は -P 4-P $(nproc)(CPUコア数)を指定するのが安全です。

3.3 grepで見つかったファイル群をまとめて別のディレクトリへコピーする

grep -rl で特定のエラーログや設定文字列を含むファイル一覧を抽出し、xargs で一括コピー・バックアップします。GNU cp-t(ターゲットディレクトリ指定)オプションと組み合わせると非常にスマートに記述できます。

# "FATAL_ERROR" を含むログファイル群をまとめて /tmp/error_logs/ に一括コピー
grep -rl "FATAL_ERROR" /var/log/ | xargs -r cp -t /tmp/error_logs/

# -I {} を使用して個別に移動する場合
grep -rl "DEPRECATED" src/ | xargs -r -I {} mv {} /tmp/deprecated/

grep コマンドの詳しい使い方・正規表現レシピ も参照してください。

3.4 gitの不要なマージ済みローカルブランチを一括削除する

機能開発が終わってリモートにマージされたローカルブランチはどんどん溜まっていきます。git branch --mergedxargs を組み合わせれば、保護対象(main, master, develop)を除外して一括クリーンアップできます。

# マージ済みブランチを一覧抽出し、現在のブランチとmain/masterを除外して一括削除
git branch --merged | grep -Ev '^\*|main|master|develop' | xargs -r git branch -d

3.5 プレースホルダー(-I)を使って引数の位置を自由に配置する

通常の xargs はコマンドの末尾に引数を追加します。しかし、mvcp のように「引数を途中に挟みたい」「引数の前後に文字列や拡張子を付与したい」場合は、-I {} でプレースホルダーを指定します。

# 拡張子 .txt のファイルすべてに .bak を付与してバックアップコピー
find . -maxdepth 1 -name "*.txt" | xargs -I {} cp {} {}.bak

# 各行のホスト名に対して ping を1回ずつ送信
cat hosts.txt | xargs -I {} ping -c 1 {}

-I {} を指定すると、内部的に -L 1(1行ずつ実行)が暗黙で適用されます(詳細は後述の注意点を参照)。

3.6 -n オプションで引数を分割してバッチ処理する

一度に渡す引数の数を -n N で制限することで、メモリ消費やAPIリクエストのバッチサイズをコントロールできます。

# 引数を2個ずつ渡してコマンドを実行
echo "A B C D E F" | xargs -n 2 echo "PAIR:"

# 出力結果:
# PAIR: A B
# PAIR: C D
# PAIR: E F

3.7 カンマや改行区切りのテキストを安全に処理する(-d)

CSVやカンマ区切りの文字列を処理する際、-d(デリミタ)オプションで区切り文字を指定できます。

# カンマ区切りのユーザー名リストを1件ずつ処理
echo "alice,bob,charlie" | xargs -d ',' -n 1 echo "User:"

# 改行のみを区切りとして扱う(スペースを含む行を丸ごと1引数にする)
printf "server 01\nserver 02\nserver 03" | xargs -d '\n' -I {} echo "Connecting to [{}]"

3.8 パイプ不要!ファイルから直接引数を読み込む(-a)

無駄な cat のパイプ(UUOC: Useless Use of Cat)を避け、-a オプションで直接ファイルから引数を読み込ませるとスクリプトがすっきり高速になります。

# servers.txt に書かれた全サーバーにSSH接続してuptimeを確認
xargs -a servers.txt -I {} ssh {} "uptime"

# target_files.txt に記載されたファイルを一括削除
xargs -a target_files.txt -r rm

3.9 実行されるコマンドを画面に表示して確認する(-t)

-t(トレース)オプションを付けると、実際にどのような引数でコマンドが実行されているかを標準エラー出力に表示してくれます。スクリプトのデバッグや実行進捗の確認に便利です。

# 実行される rm コマンドの内容を表示しながら削除
echo "temp1.txt temp2.txt" | xargs -t rm
# 画面出力: rm temp1.txt temp2.txt

3.10 本番環境での誤操作防止!実行前に対話確認する(-p)

本番サーバーで重要なファイルを一括削除・変更する場合、-p オプションを付けるとコマンド実行直前に rm file1.txt file2.txt ?... と確認プロンプトが表示され、y または yes を入力しない限り実行されません。

# 実行前にプロンプトで確認(y で実行、n でスキップ)
find . -name "*.bak" | xargs -p rm
# 表示: /bin/rm ./old.bak ./test.bak ?...

3.11 空入力での誤動作を防ぐ(-r / –no-run-if-empty)

標準の xargs は、入力が空であってもコマンドを1回実行してしまいます(例: echo "" | xargs rmrm 引数なしで実行されてエラーになる)。-r を付けておけば、入力が空のときは何も実行せずに正常終了します。

# 該当ファイルが0件でも余計なエラーを出さずに安全終了する
find /tmp -name "*.lock" -empty | xargs -r rm

3.12 複数ファイルの内容を sed / awk で一括置換・集計する

設定ファイル内のIPアドレスやドメイン名を一括置換したり、複数ログを集計する場合も xargs が大活躍します。

# 全設定ファイル(*.conf)内の "http://" を "https://" に一括置換
find /etc/nginx/conf.d -name "*.conf" | xargs -r sed -i 's|http://|https://|g'

# 複数ログファイルから "500 Internal Server Error" の出現数をawkで集計
find /var/log/nginx -name "access.log*" | xargs -r awk '/ 500 / {count++} END {print "500 Errors:", count}'

sed コマンドの文字列置換・一括編集レシピ および awk コマンドの集計・列抽出早見表 も参考にしてください。

3.13 特定プロセスのPIDを抽出して一括killする

ゾンビプロセスや暴走したワーカープロセスのPIDを pgrep で抽出し、xargs でまとめてシグナル送信・終了します。

# "queue-worker" という名前を含む全プロセスを安全に終了(SIGTERM)
pgrep -f "queue-worker" | xargs -r kill

# 応答しないプロセスを強制終了(SIGKILL: -9)
pgrep -f "stuck-process" | xargs -r kill -9

3.14 大量ファイルのパーミッション・所有者を一括変更する

Webサーバーの公開ディレクトリで、「ディレクトリは755、ファイルは644」に一括統一する定番の運用コマンドです。

# ディレクトリのみを 755 に一括変更
find /var/www/html -type d -print0 | xargs -0 -r chmod 755

# ファイルのみを 644 に一括変更
find /var/www/html -type f -print0 | xargs -0 -r chmod 644

# 所有者を www-data に一括変更
find /var/www/html -print0 | xargs -0 -r chown www-data:www-data

3.15 検索結果をまとめて tar アーカイブに圧縮・バックアップする

条件に合致したファイルだけを抽出して1つの .tar.gz アーカイブに固める手順です。

# 90日以上前の圧縮ログ(*.gz)を抽出して archive_2026.tar.gz にまとめる
find /var/log -name "*.gz" -mtime +90 -print0 | xargs -0 -r tar -czf /backup/old_logs.tar.gz

4. よくあるエラー・落とし穴と対処法

現場で実際に遭遇しやすい xargs の落とし穴とトラブルシューティング方法をまとめました。

4.1 ファイル名の「空白割れ」バグと -0 対策

xargs のデフォルトは空白(スペース、タブ、改行)をすべて区切り文字として認識します。そのため、"Monthly Report 2026.pdf" というファイル名を渡すと、Monthly, Report, 2026.pdf の3つの引数に分解されてしまい、「ファイルが見つかりません」というエラーや誤削除を引き起こします。

対策: 外部からファイル名を受け取る際は、必ず find -print0 | xargs -0 のようにヌル文字(\0)区切りを使用してください。

4.2 -I オプションを使うと暗黙的に「1行ずつ実行」になる仕様

-I {} を指定すると、xargs引数を1行ずつ(1件ずつ)コマンドに渡して実行(暗黙の -L 1します。1万件のファイルに対して xargs -I {} rm {} を実行すると、プロセスが1万回起動されるため非常に低速になります。

対策: 単にまとめてコマンドへ渡したいだけなら -I {} は使わず、xargs -0 rm のようにそのまま渡すか、GNUコマンドの -t オプション(例: cp -t 宛先)を活用してください。

4.3 並列実行時(-P)のログ出力混ざり対策

-P 4 などで複数プロセスを同時に動かすと、各プロセスの標準出力・標準エラー出力が端末上で混ざり合い、ログが読めなくなることがあります。

対策: 以下のように sh -c を介してプロセスごとに出力先ファイルを分けるか、logger / 各自のリダイレクトを行いましょう。

# 各プロセスの出力を個別ログファイルに分離して並列実行
cat targets.txt | xargs -P 4 -I {} sh -c 'do_heavy_job "$1" > "log_$1.txt" 2>&1' _ {}

4.4 シェル組み込みコマンドや関数が呼べない問題

cdalias、シェルスクリプト内で定義したカスタム関数は外部バイナリではないため、xargs my_function と直接呼んでも xargs: my_function: No such file or directory エラーになります。

対策: bash -c '...' _ {} を経由してシェル経由で呼び出します。自作関数の場合は export -f my_function で環境変数に関数をエクスポートしておきます。

# 自作シェル関数を定義してエクスポート
my_process() {
    echo "Processing file: $1"
}
export -f my_process

# bash -c 経由で呼び出す
find . -name "*.txt" | xargs -I {} bash -c 'my_process "$@"' _ {}

5. まとめ & 関連記事

xargs はパイプで渡されたデータを引数に変換し、大量データの一括処理や並列実行を可能にする Linux 運用の必須コマンドです。実務では以下の3原則を常に意識しましょう。

  • ファイル操作は find -print0 | xargs -0 -r が鉄則:空白割れと空入力エラーを完全に防止する。
  • 重い処理は -P $(nproc) で並列化:CPUリソースを活用してスクリプトの処理時間を劇的に短縮する。
  • 位置指定が必要な場合のみ -I {} を使う:まとめて渡せる場合は -I を避けてプロセス起動回数を抑える。

関連コマンド・リンク

Bash玄

はじめまして!Bash玄です。

エンジニアとしてシステム運用に携わる中で、手作業の多さに限界を感じ、Bashスクリプトを活用して業務を効率化したのがきっかけで、この道に入りました。「手作業は負け」「スクリプトはシンプルに」をモットーに、誰でも実践できるBashスクリプトの書き方を発信しています。

このサイトでは、Bashの基礎から実践的なスクリプト作成まで、初心者でもわかりやすく解説しています。少しでも「Bashって便利だな」と思ってもらえたら嬉しいです!

# 好きなこと
- シンプルなコードを書くこと
- コマンドラインを快適にカスタマイズすること
- 自動化で時間を生み出すこと

# このサイトを読んでほしい人
- Bashに興味があるけど、何から始めればいいかわからない人
- 定型業務を自動化したい人
- 効率よくターミナルを使いこなしたい人

Bashの世界に一歩踏み出して、一緒に「Bash道」を極めていきましょう!

Bash玄をフォローする

コメント