xargs コマンド|標準入力を引数に渡す・ find / grep との連携パターン

コマンドリファレンス

xargs コマンドは、標準入力で受け取ったデータをコマンドの引数として渡す ためのコマンドです。
findgrep などのパイプ出力を他のコマンドへ引数として渡すことで、大量のファイルやリストを効率よく一括処理できます。

構文(Syntax)

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

主なオプション一覧

オプション説明使用例
(なし)標準入力をスペース/改行区切りで引数に変換echo "a b c" | xargs echo
-n N1回のコマンド実行で使う引数の数を指定echo "1 2 3 4" | xargs -n 2 echo
-d DELIM区切り文字を指定echo "a,b,c" | xargs -d, echo
-0区切りを NUL 文字に(find -print0 と組み合わせる)find . -name "*.txt" -print0 | xargs -0 rm
-I REPLACE置換文字列を指定してコマンドに埋め込みecho "file1 file2" | xargs -n 1 -I{} cp {} /backup/
-P N最大 N 個のプロセスを並列実行cat urls.txt | xargs -P 4 -I{} curl -O {}
-p実行前に確認プロンプトを表示echo "a b" | xargs -p rm
-t実行するコマンドを表示してから実行echo "a b" | xargs -t echo
-r入力が空の場合はコマンドを実行しないecho "" | xargs -r rm

実行例

単純な引数変換

echo "file1 file2 file3" | xargs echo

出力例:

file1 file2 file3

2つずつ引数にしてコマンド実行

echo "1 2 3 4" | xargs -n 2 echo

出力例:

1 2
3 4

区切り文字を指定して処理

echo "a,b,c" | xargs -d, echo

出力例:

a b c

find と組み合わせて安全に一括処理

# 拡張子 .tmp のファイルを一括削除(スペースを含むファイル名にも安全)
find . -name "*.tmp" -print0 | xargs -0 rm
# find で見つかったすべての .log ファイルを別ディレクトリにコピー
find /var/log -name "*.log" -print0 | xargs -0 -I{} cp {} /backup/logs/
# 7日以上前のファイルをアーカイブディレクトリに移動
find . -mtime +7 -type f -print0 | xargs -0 -I{} mv {} /archive/

find コマンドの詳しい使い方 も合わせて確認してください。

grep と組み合わせてファイルを一括処理

# ERROR を含むファイル名を一覧取得して wc -l で行数カウント
grep -rl "ERROR" /var/log/ | xargs wc -l
# grep でマッチしたファイルを一括削除
grep -rl "DEPRECATED" src/ | xargs rm
# 特定文字列を含むファイルの中身を sed で一括置換
grep -rl "old_value" . | xargs sed -i 's/old_value/new_value/g'

grep コマンドの詳しい使い方 も参照してください。

プレースホルダ(-I)を使って引数を埋め込む

# ファイルを /backup/ にコピー({} に引数が入る)
echo "file1 file2" | xargs -n 1 -I{} cp {} /backup/
# 各ファイルの拡張子を変更
find . -name "*.txt" | xargs -I{} mv {} {}.bak

複数ファイルに対して sed・awk を一括実行

# 複数の設定ファイルの "localhost" を一括置換
find /etc -name "*.conf" | xargs sed -i 's/localhost/192.168.1.100/g'
# 複数ログファイルから ERROR 行だけ抽出して集計
find /var/log -name "app-*.log" | xargs awk '/ERROR/ {count++} END {print count " errors"}'

並列実行で高速化する(-P)

# 4並列で URL を一括ダウンロード
cat urls.txt | xargs -P 4 -I{} curl -O {}
# 8並列で画像を変換
find . -name "*.png" | xargs -P 8 -I{} convert {} -resize 800x {}.resized.png

実行確認しながら削除

echo "file1 file2" | xargs -p rm

空入力で実行されないようにする(-r)

# -r をつけると入力が空の場合はコマンドが実行されない
echo "" | xargs -r rm
# → rm は実行されない

関連コマンド

  • find : ファイルを検索し、その結果を xargs に渡して一括処理するときの定番の組み合わせ。-print0 | xargs -0 でスペース含むファイル名も安全に処理できる
  • grep : grep -rl でマッチしたファイル名を取得し、xargs で一括処理するパターンが実務でよく使われる
  • sed : find | xargs sed -i の組み合わせで複数ファイルを再帰的に一括置換できる
  • awk : find | xargs awk で複数ファイルのフィールド抽出・集計が可能。FILENAME 変数でどのファイルの行かも取得できる
  • parallel : GNU Parallel。xargs より高機能で並列実行が可能。より複雑な並列処理が必要な場合はこちらを検討する

備考

  • xargs はスペースや改行を区切りとするが、特殊文字や空白を含むファイル名には注意が必要。
    find -print0 | xargs -0 の組み合わせが安全。
  • デフォルトでは入力が空でもコマンドが実行されるため、不要な実行を避けたい場合は -r を使う。
  • 処理対象が非常に多い場合でも、まとめて実行することでコマンド呼び出しの回数を削減できる。
  • -P N で並列実行すると、大量ファイルの変換・ダウンロードを大幅に高速化できる。ただし書き込み競合に注意。

参考

Bash玄

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

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

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

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

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

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

Bash玄をフォローする

コメント