Linux / コマンド / xargs - 標準入力をコマンド引数として渡す

xargsは標準入力から項目を読み取り、他のコマンドの引数リストとして渡します。パイプ出力がコマンドの入力データではなく、ファイル名のような引数になる場合に使用します。

基本の区切りは空白・改行で、引用符やバックスラッシュは引用・エスケープとして解釈します。したがって任意のファイル名を扱う場合は、find -print0とxargs -0を組み合わせてNUL文字で安全に区切ります。

基本的な文法

生成コマンド | xargs [オプション] 実行コマンド [固定引数 ...]

インストールされている実装とオプションは、配布版によって異なる場合があります。man xargsで現在のシステムの説明を確認してください。

使用例

値を引数として渡す

入力行を1回以上まとめてコマンドに渡します。

printf '%s\n' one two three | xargs printf '%s\n'

ファイル名を安全に渡す

読み取れる reports ディレクトリと対象のテキストファイルを用意します。findの -print0 と組み合わせ、空白・改行・引用符を含むファイル名もNUL(値がゼロの文字)で区切ってそのまま渡します。

find reports -type f -name '*.txt' -print0 | xargs -0 -r wc -l

一度に1つずつ実行

項目ごとに別実行が必要な場合は、-n 1を使用します。

printf '%s\n' alpha beta | xargs -n 1 printf 'item: %s\n'

標準入力が引数に変わる過程

xargsは入力項目を後に指定したコマンドの引数として渡します。-n 1は項目ごとにコマンドを1回実行します。

printf 'one\ntwo\n' | xargs -n 1 printf 'item=%s\n'

例の出力:

item=one
item=two

基本のxargsは空白や改行で分割し、引用符・バックスラッシュも解釈するため、空白や改行が入ったファイル名の一覧には危険です。ファイル名を渡すときは、生成コマンドのNUL区切り出力とxargs -0を一緒に使ってください。削除のような変更コマンドと連結する前には、まずprintfで渡される引数を確認した方が安全です。

引数の1つに空白を含む場合やシェル特殊文字が含まれる場合、単純改行区切りを安全なファイル名区切りと見なしてはいけません。例えば、find ... -print0 | xargs -0 ...のように2つのコマンドの区切り方式を合わせます。GNU xargs -rは入力がないときには後のコマンドを実行しません。

主なオプションと形式

オプション・形式 説明
-0 NUL文字で項目を区切ります。
-r GNU実装では入力が空の場合は実行しません。
-n N コマンド1回実行あたり最大N個の引数を渡します。
-P N 最大N個のプロセスを同時実行します。GNU版の -P 0 は可能な限り同時実行します。
-I プレースホルダー 通常は改行単位で読み、プレースホルダーの位置へ代入します。空白だけでは分割しません。

使用する際の注意点

find ... -print | xargs rmのように改行ベースでファイル名を渡すと、空白や改行を含む名前が正しく分割されません。削除作業には NUL 区切りや find -exec を使い、対象を先に確認してください。-P による並列実行では、出力順序が一定にならず、共有ファイルへの同時書き込みなどが競合することがあります。NUL区切りでも、列挙した後に対象が置き換わる競合までは防げないため、他者が変更できるディレクトリでの削除には特に注意します。

よくある質問

パイプだけを使うことと xargs はどう違うのですか?

コマンド1 | コマンド2 はコマンド2 の標準入力に渡します。xargs は読み取った値をコマンド2 の引数として構成します。

公式ドキュメント

オプションの正確な動作や実装ごとの違いは xargs マニュアルページ で確認できます。