xargsコマンドで標準入力からコマンドを一括実行する方法|findとの組み合わせや並列処理も


この記事の監修:宮崎智広(Linux教育歴15年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtips > xargsコマンドで標準入力からコマンドを一括実行する方法|findとの組み合わせや並列処理も
「findで検索したファイルに対して、まとめてコマンドを実行したい」 「パイプで渡した結果を1つずつ処理するシェルスクリプトを書くのが面倒だ」 サーバー運用で大量のファイルを扱う場面では、こうした悩みがつきものです。そこで活躍するのが xargs(エックスアーグズ)コマンドです。 この記事では、xargs の基本的な使い方から、find との組み合わせ、ファイル名にスペースを含む場合の安全な処理、並列実行による高速化、そして実務で役立つワンライナーまで、現場で必要になるノウハウをまとめて解説します。 RHEL 9.4 / Ubuntu 24.04 LTSで動作確認済みです。

この記事のポイント

・xargs は標準入力を引数に変換してコマンドを一括実行する
・find -print0 | xargs -0 でスペース入りファイルも安全に処理
・-P オプションで複数プロセスの並列実行ができる
・-I {} で引数の挿入位置を自由に指定できる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

xargsコマンドとは?(標準入力を引数に変換する仕組み)

xargs は、標準入力から受け取ったデータを「コマンドの引数」に変換して実行するコマンドです。 名前は「eXtended ARGumentS」に由来します。 Linuxのコマンドには、パイプで渡されたデータを直接処理できるもの(grepsort など)と、引数としてファイル名やキーワードを渡す必要があるもの(rmchmodchown など)があります。 後者のコマンドに対して、パイプの出力をそのまま引数として渡す橋渡し役が xargs です。

# パイプだけでは rm にファイル名を渡せない(エラーになる) # echo "test.txt" | rm # xargs を経由すれば rm の引数としてファイル名が渡される # echo "test.txt" | xargs rm

基本的な使い方

1. 最もシンプルな実行例

xargs にコマンドを指定しない場合、デフォルトで echo が実行されます。 標準入力に渡したデータがどのように引数として組み立てられるかを確認するのに便利です。

# 改行区切りのデータを1行にまとめて出力する # echo -e "aaa\nbbb\nccc" | xargs aaa bbb ccc

このように、改行やスペースで区切られた入力が、スペース区切りの1行にまとめられます。

2. 指定したコマンドを実行する

xargs の後ろに実行したいコマンドを書くと、標準入力から受け取った値がそのコマンドの引数に渡されます。

# ファイル一覧を ls -l で詳細表示する # echo "file1.txt file2.txt file3.txt" | xargs ls -l -rw-r--r-- 1 root root 1024 Apr 14 10:00 file1.txt -rw-r--r-- 1 root root 2048 Apr 14 10:00 file2.txt -rw-r--r-- 1 root root 512 Apr 14 10:00 file3.txt

3. -n で一度に渡す引数の数を制限する

-n オプションを使うと、1回のコマンド実行で渡す引数の数を制限できます。

# 1つずつ引数を渡して echo を実行する # echo "aaa bbb ccc" | xargs -n 1 echo aaa bbb ccc # 2つずつ渡す場合 # echo "aaa bbb ccc ddd" | xargs -n 2 echo aaa bbb ccc ddd

大量のファイルを rm で削除する場合など、一度に渡す引数が多すぎると「Argument list too long」エラーが発生します。-n で制限すれば、このエラーを回避できます。

findコマンドとの組み合わせ(最頻出パターン)

xargs が最も活躍するのは、find コマンドの検索結果に対して別のコマンドを実行する場面です。

4. find | xargs の基本形

# /var/log 配下の .log ファイルをすべて表示する # find /var/log -name "*.log" -type f | xargs ls -lh -rw-r--r-- 1 root root 245K Apr 14 09:00 /var/log/messages -rw-r--r-- 1 root root 12K Apr 14 09:00 /var/log/secure -rw-r--r-- 1 root root 8.3K Apr 14 09:00 /var/log/cron

5. find -exec との違い

find には -exec オプションがあり、似たような処理ができます。 両者の違いを理解しておくと、場面に応じた使い分けができるようになります。

# find -exec は1ファイルごとにコマンドを起動する(プロセス生成コストが高い) # find /tmp -name "*.tmp" -exec rm {} \; # xargs はまとめて引数を渡す(プロセス生成が少なく高速) # find /tmp -name "*.tmp" | xargs rm

比較項目 find -exec find | xargs
プロセス起動 1ファイルごとに1回 まとめて1回(または数回)
処理速度 ファイル数が多いと遅い 高速
スペース入りファイル名 安全({} に1件ずつ入る) -0 なしだと誤動作する
数十~数百ファイル程度なら体感差はありませんが、数万ファイルを処理する場合は xargs のほうが圧倒的に速くなります。

スペースや特殊文字を含むファイル名の安全な処理

6. -print0 と -0 でヌル文字区切りにする(鉄則)

xargs はデフォルトでスペースと改行を区切り文字として扱います。 そのため、ファイル名にスペースが含まれていると、スペースの前後で分割されて誤ったファイル名がコマンドに渡されます。

# NG: スペース入りファイル名が分割されてエラーになる # find . -name "*.txt" | xargs rm rm: cannot remove 'my': No such file or directory rm: cannot remove 'document.txt': No such file or directory # OK: -print0 と -0 でヌル文字区切りにすれば安全 # find . -name "*.txt" -print0 | xargs -0 rm

find -print0 はファイル名をヌル文字(\0)で区切って出力し、xargs -0 はヌル文字を区切り文字として読み取ります。 本番環境では find | xargs の組み合わせには必ず -print0 と -0 を付ける のが安全です。ファイル名にスペースがないと確信できる場合でも、癖として付けておくことをお勧めします。

引数の挿入位置を指定する(-I オプション)

7. -I {} で引数を任意の位置に挿入する

デフォルトでは xargs は引数をコマンドの末尾に追加しますが、コマンドの途中に挿入したい場合は -I オプションを使います。

# 各ファイルを .bak 付きでコピーする # find . -name "*.conf" -print0 | xargs -0 -I {} cp {} {}.bak # 結果を確認する # ls *.conf* httpd.conf httpd.conf.bak nginx.conf nginx.conf.bak

-I {} を指定すると、{} の部分が標準入力から受け取った値に置き換わります。 なお、-I を使うと自動的に -n 1(1つずつ処理)と同じ動作になります。

8. 実務例:設定ファイルの一括バックアップ

# /etc 配下の .conf ファイルを /backup/etc/ に一括コピーする # find /etc -name "*.conf" -type f -print0 | xargs -0 -I {} cp {} /backup/etc/ # コピーされたファイル数を確認する # ls /backup/etc/ | wc -l 47

並列処理で高速化する(-P オプション)

9. -P で同時実行プロセス数を指定する

-P(parallel)オプションを使うと、複数のプロセスを同時に起動して処理を並列実行できます。

# 画像ファイルを4プロセスで並列圧縮する # find /var/www/images -name "*.png" -print0 | xargs -0 -n 1 -P 4 gzip # サーバーのCPUコア数を確認して、コア数と同じ並列度にするのが目安 # nproc 4

-P 0 を指定すると、システムが許す限りのプロセスを同時に起動します。ただし、CPU・メモリに大きな負荷がかかるため、本番サーバーでの使用は避けてください。

10. 並列実行の効果を確認する

time コマンドで、逐次処理と並列処理の実行時間を比較してみましょう。

# 逐次処理(1プロセス) # time find /data -name "*.csv" -print0 | xargs -0 -n 1 gzip real 1m23.456s # 並列処理(4プロセス) # time find /data -name "*.csv" -print0 | xargs -0 -n 1 -P 4 gzip real 0m22.123s

この例では4並列で約4倍の速度が出ています。ファイルサイズやディスクI/Oによって効果は変わりますが、CPU負荷の高い処理では大きな効果を発揮します。

実務で使えるワンライナー集

11. 古いログファイルを一括削除する

# 30日以上前のログファイルを削除する # find /var/log -name "*.log" -mtime +30 -type f -print0 | xargs -0 rm -v removed '/var/log/app/access-20260315.log' removed '/var/log/app/error-20260312.log'

12. 特定の文字列を含むファイルを検索する

grep -r でも同じことができますが、find | xargs grep のほうが対象ファイルを細かく制御できます。

# /etc 配下の .conf ファイルから "Listen" を含む行を検索する # find /etc -name "*.conf" -type f -print0 | xargs -0 grep -l "Listen" /etc/httpd/conf/httpd.conf /etc/ssh/sshd_config

13. ファイルの権限を一括変更する

# ディレクトリは755、ファイルは644に一括変更する # find /var/www/html -type d -print0 | xargs -0 chmod 755 # find /var/www/html -type f -print0 | xargs -0 chmod 644

14. 複数パッケージを一括インストールする

# packages.txt に記載されたパッケージを一括インストールする # cat packages.txt httpd php mariadb-server postfix # cat packages.txt | xargs dnf install -y

トラブルシュート・エラー対処

「Argument list too long」が出た時の対処法

大量のファイルを rm *ls * で処理しようとすると、シェルの引数長上限を超えてこのエラーが発生します。 xargs は自動的に引数を分割してくれるため、このエラーの解決策として最適です。

# NG: ファイル数が多すぎてエラーになる # rm /tmp/cache/* -bash: /bin/rm: Argument list too long # OK: xargs で分割して削除する # find /tmp/cache -type f -print0 | xargs -0 rm # 現在のシステムの引数長上限を確認するコマンド # getconf ARG_MAX 2097152

「xargs: unmatched single quote」が出た時の対処法

入力データにシングルクォートが含まれていると、xargs がクォート処理を試みてエラーになります。 -0 オプションでヌル文字区切りにするか、入力側で適切にエスケープしてください。

# NG: シングルクォート入りのファイル名でエラー # echo "it's_a_file.txt" | xargs rm xargs: unmatched single quote; ... # OK: -0 を使えばクォートの問題を回避できる # echo -ne "it's_a_file.txt\0" | xargs -0 rm

【重要】-I {} と -0 の併用時の注意

-I-0 を同時に使う場合、-0 を先に指定してください。 順序が逆だと、一部の環境で -0 が無視されることがあります。

# 推奨される書き方(-0 を先に指定する) # find . -name "*.log" -print0 | xargs -0 -I {} mv {} /archive/ # 避けるべき書き方(環境によっては -0 が無視される) # find . -name "*.log" -print0 | xargs -I {} -0 mv {} /archive/

本記事のまとめ

xargs は、標準入力から受け取ったデータをコマンドの引数に変換して実行するコマンドです。 find との組み合わせが最も多い使い方ですが、パイプで渡された結果を別のコマンドに引数として渡したい場面全般で活躍します。
やりたいこと コマンド
標準入力をまとめて引数に変換する コマンド | xargs 実行コマンド
スペース入りファイル名を安全に処理する find パス -print0 | xargs -0 実行コマンド
引数を1つずつ渡して実行する コマンド | xargs -n 1 実行コマンド
引数の挿入位置を指定する コマンド | xargs -I {} 実行コマンド {} 追加引数
並列実行で高速化する コマンド | xargs -n 1 -P 4 実行コマンド
Argument list too long を回避する find パス 条件 -print0 | xargs -0 rm
本番環境で find | xargs を使う場合は、-print0 と -0 を必ず付ける ことを忘れないでください。 ファイル名にスペースや特殊文字が含まれていないと確信できても、安全策として常に付けておくのが現場の鉄則です。

xargsを使いこなせたら、次はサーバー構築の全体像を学びませんか?

xargsでファイル操作を自動化できるようになると、サーバー管理の効率が格段に上がります。その力を活かして、体系的にLinuxサーバー構築を学んでみませんか。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。


暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録

宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として15年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。