KEIS BLOGは株式会社ケイズ・ソフトウェアが運営しています。

KEIS BLOG

xargs徹底活用ガイド — パイプの先でさらなる力を引き出す


Linuxのコマンドラインで作業してると、grepfindなどで得た結果を別のコマンドに渡したい時が良くあります。

その時、単純なパイプでは実現しづらい、「コマンドの出力を引数として別コマンドに渡す」操作を可能にするのがxargsです。

 

なんか理解しにくいコマンドではあるんですけど、使いこなすとめっちゃ強力なコマンドなんで、
本記事ではxargsをとことん掘り下げて、理解と活用の幅を広げる方法を紹介しますね。


xargsとは?

xargsは、標準入力(stdin)から受け取った文字列を引数として、指定したコマンドを実行するツールです。つまり、

  1. あるコマンドでファイル名や文字列のリストを標準出力へ
  2. **xargs**でそのリストを引数として別コマンドに渡す

この手順によって、複雑なコマンドチェーンを簡潔に記述できます。

シンプルな例

echo "file1 file2 file3" | xargs rm

この例では、echoによって標準出力に”file1 file2 file3″が流れます。xargs rmは、その文字列をrm file1 file2 file3という形で解釈して実行してくれます。


なぜxargsが必要なのか?

多くのコマンドは標準出力に結果を出しますが、その出力を「引数として」受け取りたい場合、パイプ|だけではうまくいかないことがあります。
たとえば、findコマンドは検索結果を標準出力に出しますが、複数のファイルを処理したいときにfindの出力を直接削除コマンドに渡すと、引数として解釈されないことがあります。

# こうしたい → findした結果をrmの引数にしたい
find . -name "*.txt" | rm

しかし、これは動きません。rmは標準入力から削除対象を受け取るような作りではないからです。
そこでxargsを用いると、

find . -name "*.txt" | xargs rm

これでfindの結果(*.txtファイルの一覧)をrmの引数として渡せます。

※「-exec rm {} \; すればいいだけじゃん」とか言わない。例だから!


基本的な使い方

1. スペース・改行・タブで区切られた文字列を引数にする

xargsは標準的には、空白文字(スペース・タブ・改行)で区切られた単語を引数として扱います。

echo "file1 file2 file3" | xargs ls -l

これでls -l file1 file2 file3が実行されます。

2. 複数行出力に対しても同様

echo -e "file1\nfile2\nfile3" | xargs ls -l

\n(改行)で区切られた文字列も引数として扱われ、ls -l file1 file2 file3が実行されます。


よくあるオプションとテクニック

-nオプション — 引数をまとめる数を制御する

xargsは、受け取った引数が非常に多い場合、一度にすべての引数を渡そうとしてコマンドラインが長すぎるエラーになることがあります。
そんなときは-nオプションで「1回のコマンド実行で何個の引数を渡すか」を指定できます。

cat list_of_files.txt | xargs -n 10 rm

list_of_files.txtにファイル名が100個書いてあっても、rmは10ファイルずつ処理します(合計10回実行)。

-Iオプション — プレースホルダーを使う

引数の挿入位置を指定できるオプション-Iは、xargsをより柔軟にします。
-I {}のように書くと、{}を引数挿入位置として扱うことができます。

echo "file1 file2 file3" | xargs -I {} mv {} /backup/

ここでは{}mvの引数部分に置き換えて、mv file1 /backup/, mv file2 /backup/, mv file3 /backup/を順番に実行します。
これにより、引数を複数箇所に挿入したり、コマンド構造を柔軟に変えることができます。

-0オプション — NULL文字区切りへの対応

xargsはデフォルトで空白を区切り文字としますが、ファイル名に空白や特殊文字が含まれると問題になります。そこで、-0オプション(ゼロオプション)を使い、NULL文字(\0)区切りの入力を扱うことが可能です。

findコマンドの-print0オプションと組み合わせると、空白を含むファイル名を安全に処理できます。

find . -type f -print0 | xargs -0 rm

これで、空白を含むファイル名でも正しくrmへ渡せます。まあ、滅多に使わないけど、やり方忘れて「どやっけ」ってなるのでメモも兼ねて・・・。


実用的な活用例

1. 大量ファイルのバッチ処理

例えば、大量の.logファイルをまとめて圧縮したい場合:

find /var/log -name "*.log" | xargs tar cvf logs.tar

こうすると、findで見つけた全.logファイルをtarに渡し、ひとつのアーカイブlogs.tarにまとめられます。

2. フィルタリングした結果を別コマンドへ

grepで特定のファイルパターンを抽出し、それに対して別の操作をする場合:

grep -rl "ERROR" /path/to/logs | xargs -I {} cp {} /path/to/error_logs/

grep -rl "ERROR"はERROR文字列を含むファイルパスを表示します。それをxargsで受け、cpコマンドをエラー発生ログファイルごとに実行。ここでは-I {}を使ってファイル名をcpに挿入しています。

3. 複雑な置き換えとコマンド組み立て

ファイル名を加工して別ディレクトリへ移動する、たとえば.txtファイルを.bak拡張子に変更してバックアップフォルダに移動する場合:

ls *.txt | sed 's/\.txt$/.bak/' | xargs -I {} mv {} backup/

ここでsedでファイル名拡張子を変換し、その結果をxargsmvコマンドに渡しています。-I {}によって、{}が変換後のファイル名に置き換えられます。

4. 並列実行(-Pオプション)

xargsには-Pオプションで並列実行数を指定できるという強力な機能もあります。多くの処理を同時並行で実行したい場合に便利です。

cat tasks.txt | xargs -n 1 -P 4 sh -c

tasks.txtに、実行したいコマンドが1行に1つ書いてあるとします。
-n 1で1行につき1コマンド、-P 4で同時に4プロセスまで並行実行を行います。これでバッチ処理のスピードアップが可能です。
並列処理がこんなに簡単に書けちゃうのすごくないっすか?


トラブルシューティング

  • 引数が多すぎるエラーxargsは自動的にコマンドラインが長くなりすぎないように分割して実行してくれますが、-nで明示的に分割数を指定すると安全。
  • 空白や特殊文字を含むファイル名の処理-0オプション + find -print0grep -Zを利用することで確実な処理が可能。
  • スクリプトで使う場合xargsの実行結果を安定させるため、オプションを明示的に指定したり、-Iプレースホルダーを活用すると予期せぬ挙動を避けられます。

まとめ

xargsは、単純なリスト変換コマンドに見えますが、実は

  • パイプを介した引数連携
  • 大量ファイルへのバッチ処理
  • 複雑なコマンド構築の自動化
  • 並列実行による効率化

といった、多様な活用を可能にする強力なツールです。

使いこなす鍵は、オプション(-n, -I, -0, -P)を理解し、find, grep, sed, awkなど他のコマンドと組み合わせること。
xargsをマスターすれば、コマンドラインでの作業効率が一気に向上し、スクリプト記述やデータ処理を大幅に簡潔化できます。

使い方覚えるには日々のオペレーションやスクリプト作成でxargsを使いまくってください。
コマンドライン使いこなし力がもう一個アップします!