xargsコマンド:使い方と-n・-Iオプション、findとの組み合わせ

テスト環境RHEL系AlmaLinux 9.8rootアカウント2026-10-29 確認

xargsコマンドは、標準入力で受け取った行や単語を別のコマンドの引数に変えて実行するLinuxのツールです。AlmaLinux 9サーバーの作業フォルダーで、findが見つけたログファイル3つをxargsでwcに渡してみると、名前に空白を含むファイル1つが2つに分かれてエラーになり、-print0と-0を付けると3つのファイルの行数がすべて表示されました。

以下の出力は、AlmaLinux 9.8サーバーのrootアカウントで作業フォルダー内で実行した結果です。名前の一覧とログ、一時ファイルはテスト用に作ったサンプルファイルで、その中のIPアドレスと作業フォルダーのパスも例の値です。

1️⃣ xargsコマンドの基本的な使い方

  • ↪️ 標準入力をコマンドの引数に

xargsは前のコマンドから渡された標準入力を空白と改行で分け、後ろに書いたコマンドの引数の位置に付けて実行します。1行に名前が1つずつ入ったnames.txtで確認しました。

cat names.txt
alice
bob
carol
dave
erin

catの出力をxargs echoに渡すと、5行がechoを1回実行するときの引数になり、1行で表示されます。

cat names.txt | xargs echo
alice bob carol dave erin

後ろにコマンドを書かないとxargsはechoを実行するので、結果は同じです。

cat names.txt | xargs
alice bob carol dave erin

パイプは前のコマンドの出力を後ろのコマンドの標準入力につなぐ通路なので、後ろのコマンドの引数の位置には何も入りません。ファイル名が3つ入ったlist.txtをwc -lにパイプだけで渡すと、wcは一覧自体の行数3を数えます。

cat list.txt
logs/access.log
logs/error.log
tmp/keep.txt
cat list.txt | wc -l
3

間にxargsを置くと、一覧の3つの名前がwcの引数になり、ファイルごとの行数が表示されます。

cat list.txt | xargs wc -l
  3 logs/access.log
  2 logs/error.log
  1 tmp/keep.txt
  6 total

2️⃣ xargsの-nと-Iオプション

  • ↪️ まとめる数、引数の位置、-tでの確認

オプションがないと入力のすべてが1回のコマンドに入るので、コマンドを繰り返し実行するには-nで1回に渡す引数の数を決めます。以下の図で、同じ5つの名前がオプションによってどうまとめられるかを確認できます。

🧩 xargsが標準入力をコマンドの引数にまとめる方式
解説ダイアグラム
⚙️ オプション
$ cat names.txt | xargs echo
$ cat names.txt | xargs -n 2 echo
$ cat names.txt | xargs -I {} echo 'user: {}'
① 標準入力 (names.txt)alicebobcaroldaveerin1行に名前が1つ、全5行です。
② 引数にまとめるalicebobcaroldaveerinオプションがないと5つを1つのまとまりにします。alicebobcaroldaveerin-n 2は2つずつまとめ、残った1つは別にまとめます。alicebobcaroldaveerin-I {}は1行を1つのまとまりとし、{}の位置に入れます。
③ 実行されるコマンドと出力echo alice bob carol dave erinalice bob carol dave erinechoが1回実行されます。echo alice bobecho carol daveecho erinechoが3回実行され、まとまりごとに1行ずつ表示されます。echo 'user: alice' echo 'user: bob' … erinまで同じ形で5回user: aliceuser: bobuser: caroluser: daveuser: erinechoが5回実行され、{}の位置に名前が入ります。
オプションがないと、xargsは入力から読んだ単語のすべてを1回のコマンドの引数に付けます。5つの名前が1回のechoに渡され、1行で表示されます。
-n 2を付けると、単語を2つずつまとめてコマンドを繰り返し実行します。5つの名前は3つのまとまりになり、echoが3回実行されます。
-I {}を付けると1行を1つとして扱い、コマンド内の{}の位置にその行を入れて行ごとに実行します。引数を末尾以外の位置に入れる必要があるときに使います。

-n 1は名前1つごとにechoを実行し、5行表示されます。

cat names.txt | xargs -n 1 echo
alice
bob
carol
dave
erin

-n 2は2つずつまとめ、残った1つは別に渡します。

cat names.txt | xargs -n 2 echo
alice bob
carol dave
erin

実行されるコマンドを目で確認するには-tを付けます。コマンドの行が先に表示され、その下に出力が続きます。

cat names.txt | xargs -t -n 2 echo
echo alice bob
alice bob
echo carol dave
carol dave
echo erin
erin

引数をコマンドの末尾以外の位置に入れる必要があるときは、-Iでプレースホルダーを決めます。{}の位置に1行ずつ入り、同じ文字が複数あるとすべて置き換わります。

cat names.txt | xargs -I {} echo 'user: {}'
user: alice
user: bob
user: carol
user: dave
user: erin
cat names.txt | xargs -I {} echo '{} -> home/{}'
alice -> home/alice
bob -> home/bob
carol -> home/carol
dave -> home/dave
erin -> home/erin

同じ方法で名前ごとにフォルダーを作れます。homeフォルダーを先に作ってから-I {}でその下に名前別のフォルダーを作ると、5つのフォルダーができます。

mkdir home
cat names.txt | xargs -I {} mkdir home/{}
ls home
alice  bob  carol  dave  erin

-Iは1行を1つの引数として扱うので、-nと一緒には使えません。2つを一緒に書いたときは警告とともに-Iが無視され、{}が文字どおり出力されました。

cat names.txt | xargs -I {} -n 2 echo {}
xargs: warning: options --replace and --max-args/-n are mutually exclusive, ignoring previous --replace value
{} alice bob
{} carol dave
{} erin

-Lは行数でまとめます。1行に単語が複数あるとその行の単語が一緒に渡され、1行に名前が1つしかないnames.txtでは-L 2が-n 2と同じ結果になりました。

cat names.txt | xargs -L 2 echo
alice bob
carol dave
erin

3️⃣ findとxargsの組み合わせ

  • ↪️ -print0と-0で空白を含むファイル名を渡す

名前の一覧を手で作らなくても、findが見つけたファイルの一覧をそのままxargsに渡せます。ログフォルダーで.logで終わるファイルを探すと3つ見つかり、そのうち1つは名前に空白が入っています。

find /root/work/logs -name '*.log'
/root/work/logs/access.log
/root/work/logs/error.log
/root/work/logs/old access.log

この一覧をそのままxargs wc -lに渡すと、空白を含む名前がoldとaccess.logの2つに分かれてエラーが2行表示され、合計も2つのファイルだけを足した5行でした。

find /root/work/logs -name '*.log' | xargs wc -l
  3 /root/work/logs/access.log
  2 /root/work/logs/error.log
wc: /root/work/logs/old: No such file or directory
wc: access.log: No such file or directory
  5 total

findの-print0は名前の間を改行の代わりにヌル文字で区切り、xargsの-0はそのヌル文字だけで引数を分けます。両方を付けると、空白を含むファイルまで3つのファイルの行数が表示されます。

find /root/work/logs -name '*.log' -print0 | xargs -0 wc -l
  3 /root/work/logs/access.log
  2 /root/work/logs/error.log
  1 /root/work/logs/old access.log
  6 total

findの-execオプションでも同じことができます。{}の後に+を付けると見つけたファイルを一度に渡すので結果は同じで、ファイル名の空白もfindがそのまま渡します。xargsはfind以外のコマンドの出力も受け取れるので、入力がfindだけではないときに使い、1回に渡す数(-n)や同時実行数(-P)を決める必要があるときもxargsを使います。

find /root/work/logs -name '*.log' -exec wc -l {} +
  3 /root/work/logs/access.log
  2 /root/work/logs/error.log
  1 /root/work/logs/old access.log
  6 total

見つけたファイルのうち文字列を含むファイルだけを選ぶには、xargsの後にgrep -lを付けます。wp-loginを含むファイルはアクセスログとエラーログの2つでした。

find /root/work/logs -name '*.log' -print0 | xargs -0 grep -l wp-login
/root/work/logs/access.log
/root/work/logs/error.log

4️⃣ xargsコマンドでのファイル削除

  • ↪️ echoで先に見て-pで確認する

xargsの後にrmを付けると見つけたファイルが一度に削除されるので、削除する前にどのファイルが渡されるかを先に確認します。rmの前にechoを置くと、実行されるコマンドの行だけが表示され、ファイルはそのまま残ります。

find /root/work/tmp -name '*.tmp' -print0 | xargs -0 echo rm
rm /root/work/tmp/cache-a.tmp /root/work/tmp/cache-b.tmp /root/work/tmp/cache-c.tmp
ls tmp
cache-a.tmp  cache-b.tmp  cache-c.tmp  keep.txt

-pを付けると、コマンドごとに実行するかどうかを聞きます。nを入力すると何も削除されず、一時ファイル3つがそのまま残ります。

find /root/work/tmp -name '*.tmp' -print0 | xargs -0 -p rm
rm /root/work/tmp/cache-a.tmp /root/work/tmp/cache-b.tmp /root/work/tmp/cache-c.tmp?...n
ls tmp
cache-a.tmp  cache-b.tmp  cache-c.tmp  keep.txt

yを入力すると3つのファイルが削除され、keep.txtだけが残ります。

find /root/work/tmp -name '*.tmp' -print0 | xargs -0 -p rm
rm /root/work/tmp/cache-a.tmp /root/work/tmp/cache-b.tmp /root/work/tmp/cache-c.tmp?...y
ls tmp
keep.txt

入力が空だと、xargsはコマンドを引数なしで1回実行します。空のファイルを渡すとrmが引数なしで実行されて[rm: missing operand]エラーになり、-rを付けるとコマンド自体が実行されません。

cat empty.txt | xargs rm
rm: missing operand
Try 'rm --help' for more information.
cat empty.txt | xargs -r rm

5️⃣ xargsコマンドの並列実行、区切り文字とオプション

  • ↪️ -P、-d、-aオプション

🔲 並列実行と区切り文字

コマンドが1つずつ順に実行されると、対象が多いときにその分だけ時間が延びます。-Pは同時に実行するコマンドの数を決めます。1秒、2秒、3秒、4秒待つsleep 4つは、順に実行すると10秒、-P 4で同時に実行すると最も長い4秒で終わりました。

time seq 1 4 | xargs -n 1 sleep

real	0m10.007s
user	0m0.004s
sys	0m0.003s
time seq 1 4 | xargs -n 1 -P 4 sleep

real	0m4.005s
user	0m0.001s
sys	0m0.006s

入力が改行や空白ではない記号で分かれているときは、-dで区切り文字を決めます。カンマでつないだ3つの名前を-d ,で分けると、名前ごとに1行ずつ表示されます。

printf 'alice,bob,carol' | xargs -d , -n 1 echo
alice
bob
carol

標準入力の代わりにファイルから読むには、-aにファイル名を書きます。パイプなしでnames.txtの5つの名前がechoに渡されました。

xargs -a names.txt echo
alice bob carol dave erin

🔲 xargsコマンドのオプション

📌 主なオプション: この記事で実行した結果

オプション作業この記事で確認した結果
-n1回のコマンドに渡す引数の数を決める5つの名前が-n 2で2つずつまとめられ、echoが3回実行
-Iプレースホルダーに1行ずつ入れて行ごとに実行{}の位置に名前が入る、-nと一緒に書くと警告とともに-Iが無視される
-L1回のコマンドに渡す行数を決める1行に名前が1つしかないファイルでは-n 2と同じ結果
-t実行するコマンドの行を先に出力コマンドの行が出力より先に表示
-0ヌル文字だけで入力を分ける(find -print0と一緒に)なければ空白を含む名前が分かれてエラー2行、付けると3つのファイルがすべて6行
-pコマンドごとに実行するかどうかを聞くnならそのまま残り、yなら3つのファイルを削除
-r入力が空ならコマンドを実行しないなければ[rm: missing operand]、付けると実行しない
-P同時に実行するコマンドの数を決めるsleep 4つが順に10秒、-P 4で4秒
-d入力を分ける区切り文字を決める-d ,で名前ごとに1行
-a標準入力の代わりにファイルから入力を読むnames.txtの5つの名前が1回のechoに

📎 その他のオプション: 公式マニュアルより

オプション作業
-sコマンド1行に使える最大文字数を決める
-x-sのサイズを超えると実行せずに終了
-E入力でこの文字だけの行に達すると残りの入力を読まない
-o実行するコマンドの標準入力をターミナルに開き直す(対話型プログラム用)
--process-slot-var同時に実行されるコマンドごとに環境変数へ別の番号を入れる

🔲 xargsコマンドシミュレーター

以下のシミュレーターで、同じテストファイルにxargsとfindのコマンドを実際に入力できます。

xargsコマンドシミュレーターGNU findutils 4.8
[root@server work]#
キーボードの↑↓で、前に入力したコマンドを呼び出せます。

🔢 FAQ & おすすめコンテンツ

プロセス番号を渡すと、killがその番号へシグナルを送ります。バックグラウンドで実行したsleep 600のプロセス番号をシェル変数$!で取り出してxargs killに渡すと、ジョブ一覧に[Terminated sleep 600]が残り、次のjobsではジョブが消えました。番号の一覧を別のコマンドで集めるときは、どのプロセスが含まれるかを先に出力してから渡します。

--show-limitsオプションが上限を出力します。テストしたサーバーでは、コマンド行の長さのPOSIX上限が2,093,890バイトで、xargsが実際に使うコマンドバッファーは131,072バイトでした。マニュアルによると、入力がこのバッファーより長いと、xargsはコマンドを複数回に分けて実行します。

xargsが実行したコマンドのうち1つでも1から125の間のコードで失敗すると、xargsの終了コードは123になります。空白を含むファイル名が分かれたwcの実行も、空の入力でrmを実行した場合も123で、コマンドが見つからなかった場合は127でした。シェルスクリプトでxargsの後の終了コードを調べるときは、この値を基準にします。

ℹ️ 提携について
当サイトのコンテンツにはアフィリエイトリンクが含まれています。訪問者がこのリンクを通じて商品やサービスを購入すると、当サイトは販売元から手数料を受け取ります。この過程において、購入者が支払う金額(イベント割引適用で金額が下がります↓)は上昇しません。掲載されている価格・割引・在庫情報は作成時点のものであり、実際とは異なる場合がありますので、ご購入前に販売元にて最終確認をお願いいたします。商品の選定および評価は独自の基準に基づいて行われており、手数料の支払いの有無は紹介順や評価内容に影響を与えません。

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

人間であることを証明してください: 4   +   1   =