xargsコマンドの使い方|findやgrepの出力を引数に渡して一括処理する方法


図解60p「Linuxサーバー構築入門マニュアル」無料
登録10秒/自動返信でDL/合わなければ解除3秒
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxコマンド, LinuxコマンドU-Z, ファイル・ディレクトリ管理コマンド > xargsコマンドの使い方|findやgrepの出力を引数に渡して一括処理する方法
「findで見つけたファイルをまとめて削除したいのに、パイプでつなぐとうまくいかない」
「コマンドの引数にファイル一覧を渡したいけど、数が多すぎてエラーになる」

xargsは、標準入力から受け取ったデータをコマンドの引数として渡すコマンドです。findやgrepの出力をそのまま別のコマンドに引き渡せるため、ファイルの一括処理やログの一括検索など、日常的なサーバー管理作業を大幅に効率化できます。
この記事では、xargsの基本的な使い方から、スペースを含むファイル名の安全な処理、並列実行、find -execとの使い分けまで、実務で必要な知識を網羅します。

なぜxargsが必要なのか?~パイプだけでは解決できない場面~

Linuxでは、コマンドの出力をパイプ(|)で次のコマンドに渡すのが日常的です。しかし、パイプが渡すのは「標準入力」であって「引数」ではありません。

この違いが問題になる典型例を見てみましょう。

# これは動かない(rmは標準入力を受け付けない) find /tmp -name "*.log" | rm # xargsを使えば、findの出力をrmの「引数」として渡せる find /tmp -name "*.log" | xargs rm

grepやcatのように標準入力を読み取るコマンドならパイプだけで動きます。しかし、rm、cp、mv、chown、chmodなどは「引数」としてファイル名を受け取るため、パイプだけでは渡せません。

xargsは、この「標準入力 → 引数」の変換を担うコマンドです。

基本的な使い方

1. find | xargs の基本パターン

最も使用頻度が高いのが、findの出力をxargsで別のコマンドに渡すパターンです。

# /var/log 配下の .log ファイルを一覧表示 find /var/log -name "*.log" | xargs ls -l # 30日以上前の一時ファイルを削除 find /tmp -type f -mtime +30 | xargs rm -f

xargsは受け取った入力を、スペースや改行で区切って引数に変換します。上の例では、findが出力したファイルパスがそのままrmの引数として渡されます。

2. -I {} でプレースホルダを指定する

デフォルトのxargsは、引数をコマンドの末尾に追加します。引数を任意の位置に挿入したい場合は -I {} を使います。

# ファイルをバックアップディレクトリにコピー find /etc -name "*.conf" | xargs -I {} cp {} /backup/ # ファイル名の前後に文字を追加してリネーム ls *.txt | xargs -I {} mv {} old_{}

-I {} を指定すると、入力を1行ずつ処理します。{} の部分が入力値に置き換わるため、コマンドの途中に引数を挿入できます。

3. -print0 と -0 でスペースを含むファイル名を安全に処理する

xargsの最大の落とし穴は、スペースを含むファイル名の扱いです。デフォルトではスペースが区切り文字として解釈されるため、「my file.txt」が「my」と「file.txt」の2つに分割されてしまいます。

# 安全な書き方(NULL文字で区切る) find /home -name "*.txt" -print0 | xargs -0 rm -f # NG(スペースを含むファイル名が分割される) find /home -name "*.txt" | xargs rm -f

findの -print0 はファイル名をNULL文字(\0)で区切って出力し、xargsの -0 はNULL文字を区切りとして受け取ります。この組み合わせにより、スペースや特殊文字を含むファイル名でも正しく処理できます。

※ 本番環境でfind | xargsを使う場合は、常に -print0 | xargs -0 の組み合わせを使うのが鉄則です。

4. echo や cat からの入力

findだけでなく、echoやcatの出力もxargsに渡せます。

# スペース区切りの文字列を1つずつ処理 echo "server1 server2 server3" | xargs -n 1 ping -c 1 # ファイルに書かれたホスト一覧に対してコマンドを実行 cat hosts.txt | xargs -I {} ssh {} "uptime"

5. -n で引数の個数を制限する

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

# 引数を2個ずつに分割して実行 echo "a b c d e f" | xargs -n 2 echo # 実行結果 a b c d e f

大量のファイルを処理する際に、一度に渡す引数の数を制御できるため、メモリや処理負荷の調整に役立ちます。

応用・実務Tips

1. grep -l | xargs sed -i で複数ファイルを一括置換

設定ファイルの一括変更は、サーバー管理で頻繁に発生する作業です。

# 「old_server」を含むファイルを検索し、一括で「new_server」に置換 grep -rl "old_server" /etc/ | xargs sed -i "s/old_server/new_server/g" # 置換前に対象ファイルを確認(安全策) grep -rl "old_server" /etc/ | xargs ls -l

grep -r の -l オプションは、マッチした「行」ではなく「ファイル名」だけを出力します。これをxargsでsed -iに渡すことで、複数ファイルの一括置換が1行で完了します。

※ 本番環境では、置換前に必ず対象ファイルを確認してください。

2. find + xargs vs find -exec の使い分け

findで見つけたファイルにコマンドを実行する方法は2つあります。

# xargs方式(高速:コマンドをまとめて実行) find /var/log -name "*.log" -print0 | xargs -0 gzip # -exec方式(1ファイルずつ実行) find /var/log -name "*.log" -exec gzip {} \; # -exec +方式(xargsと同様にまとめて実行) find /var/log -name "*.log" -exec gzip {} +

xargs方式:引数をまとめて渡すため、コマンドの起動回数が少なく高速。大量ファイルの処理に向く
-exec \;方式:1ファイルずつコマンドを起動するため遅いが、確実に1つずつ処理できる
-exec +方式:xargsと同様にまとめて実行。外部コマンドへのパイプが不要な分シンプル

基本的にはxargs方式か -exec + 方式を使い、ファイル名にスペースが含まれる可能性がある場合は -print0 | xargs -0 が最も安全です。

3. -P で並列実行する

-P オプションで、複数のプロセスを同時に実行できます。CPUやネットワークがボトルネックにならない処理では、大幅な時間短縮が可能です。

# 4並列でgzip圧縮を実行 find /var/log -name "*.log" -print0 | xargs -0 -P 4 gzip # 8並列で画像をリサイズ(ImageMagick) find /images -name "*.jpg" -print0 | xargs -0 -P 8 -I {} convert {} -resize 800x600 {}

-P 0 を指定すると、可能な限り多くのプロセスを同時実行します。ただし、サーバーの負荷に注意してください。

4. -p で確認プロンプト付き実行、-t で実行コマンドを表示

削除や変更を伴う操作では、実行前の確認が重要です。

# 実行前にy/nの確認プロンプトを表示 find /tmp -name "*.bak" | xargs -p rm -f # 実行するコマンドを標準エラー出力に表示(デバッグ用) find /var/log -name "*.log" | xargs -t gzip

-p はy(yes)を入力しない限り実行しないため、本番環境での安全策として有効です。-t は実行されるコマンドを表示するだけで、確認なしに実行します。

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

1. ファイル名にスペースや特殊文字がある場合の問題

xargsのデフォルトでは、スペース・タブ・改行が区切り文字です。ファイル名にこれらが含まれると、意図しない分割が発生します。

# 問題の例:"my report.txt" が "my" と "report.txt" に分割される echo "my report.txt" | xargs rm # rm: cannot remove 'my': No such file or directory # rm: cannot remove 'report.txt': No such file or directory # 解決策:-print0 と -0 を組み合わせる find /home -name "*.txt" -print0 | xargs -0 rm -f # find以外の入力では -d でデリミタを改行に変更する ls | xargs -d '\n' rm -f

2. 「Argument list too long」エラーの回避

ワイルドカード展開でファイル数が多すぎると、シェルの引数長制限に引っかかります。xargsを使うことでこのエラーを回避できます。

# エラーになるケース(ファイル数が多すぎる) rm /tmp/logs/*.log # -bash: /bin/rm: Argument list too long # xargsで回避(自動的に分割して実行) find /tmp/logs -name "*.log" | xargs rm -f # 現在のシステムの引数長制限を確認 getconf ARG_MAX

xargsは、引数の合計サイズがシステムの制限(ARG_MAX)を超えないように、自動的に複数回に分割してコマンドを実行します。これがxargsの最も重要な機能の1つです。

3. xargsに渡すコマンドでリダイレクトを使う方法

xargsの中でリダイレクト(>や>>)を直接使うことはできません。シェルがxargsの実行前にリダイレクトを解釈してしまうためです。

# NG(リダイレクトがxargsではなくシェルに解釈される) find /var/log -name "*.log" | xargs head -1 > result.txt # OK(sh -c でサブシェルを使う) find /var/log -name "*.log" | xargs -I {} sh -c "head -1 {} >> result.txt" # OK(ファイルごとに別のファイルに出力) find /var/log -name "*.log" | xargs -I {} sh -c "wc -l {} > {}.count"

sh -c を使うことで、リダイレクトやパイプをxargsの中で利用できます。複雑な処理を行う場合は、sh -c の中にコマンドを書くのが定石です。

4. 入力が空の場合の挙動

xargsに空の入力が渡された場合、GNU版(Linux標準)ではコマンドを実行しません。ただし、明示的に制御したい場合は --no-run-if-empty(-r)を付けます。

# 入力が空ならコマンドを実行しない(GNU xargsではデフォルトの動作) find /tmp -name "*.nonexistent" | xargs --no-run-if-empty rm -f # 短縮形 find /tmp -name "*.nonexistent" | xargs -r rm -f

本記事のまとめ

xargsの主要な使い方を一覧にまとめます。
やりたいこと コマンド
findの結果にコマンドを実行 find パス 条件 | xargs コマンド
スペースを含むファイル名を安全に処理 find パス 条件 -print0 | xargs -0 コマンド
引数を任意の位置に挿入 find パス 条件 | xargs -I {} コマンド {}
引数の個数を制限して実行 find パス 条件 | xargs -n 数 コマンド
複数ファイルを一括置換 grep -rl "文字列" パス | xargs sed -i "s/旧/新/g"
並列実行で処理を高速化 find パス 条件 -print0 | xargs -0 -P 並列数 コマンド
確認プロンプト付きで実行 find パス 条件 | xargs -p コマンド
実行コマンドを表示 find パス 条件 | xargs -t コマンド
リダイレクトを使う find パス 条件 | xargs -I {} sh -c "コマンド {} > 出力先"
Argument list too longを回避 find パス -name "パターン" | xargs rm -f

xargsを使いこなして、日々のサーバー管理を効率化しませんか?

xargsは、findやgrepと組み合わせることで真価を発揮するコマンドです。こうしたコマンド連携の「型」を身につけることで、作業スピードが大きく変わります。
ネットの切れ端の情報をコピペするだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

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



無料プレゼント
図解60p「Linuxサーバー構築入門マニュアル」
独学で詰まる前に、“型(手順書)”で最初の環境構築をサクッと終わらせましょう。
登録10秒/自動返信でDL/合わなければ解除3秒
無料で受け取る ※メールアドレスだけでもOK(必須項目は最小限)

宮崎 智広

この記事を書いた人

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

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

図解60pのLinux無料マニュアル
登録10秒/自動返信でDL
無料で受け取る