xargsコマンド
xargsの特徴
xargsコマンドは、空白や改行で区切られた一連の項目を読み込み、他のコマンドに引数として渡す。
コマンドが受け取ることができる引数の数やサイズには制限があるため、大量のリストを受け付けられないことがある。そこでxargsがリストを分割して、何回かに分けてコマンドを実行する。次の例では10個のファイルを5個ずつコマンドに渡している。
find -name '*file*' -type f
(out)./file6.txt
(out)./file3.txt
(out)./file10.txt
(out)./file9.txt
(out)./file7.txt
(out)./file1.txt
(out)./file8.txt
(out)./file2.txt
(out)./file5.txt
(out)./file4.txt
find -name '*file*' -type f | xargs -t -r -L 5 wc
(out)wc ./file6.txt ./file3.txt ./file10.txt ./file9.txt ./file7.txt
(out) (wcの結果は省略)
(out)wc ./file1.txt ./file8.txt ./file2.txt ./file5.txt ./file4.txt
(out) (wcの結果は省略)
これがxargsの本質である、引数を拡張する(Extanded Arguments)挙動である。リストのサイズが大きい場合、指定が無くても自動で複数に分割される。多数のリストをseqコマンドで作成してxargsに渡してみる。
seq 100 | xargs | wc -l
(out)1
seq 100000 | xargs | wc -l
(out)5
xargsはコマンドが指定されなかった場合、項目を引数として展開した上で標準出力へ出力する。その出力をwcで数えている。100行のリストであれば1回でコマンドにまとめて渡そうとするが、100000行のリストだと5回に分けてコマンドを実行しようとしている。
$ ls
(out)data1.txt data2.txt
ls | xargs -t -r wc
(out)wc data1.txt data2.txt
(out) 17 865 5899 data1.txt
(out) 13 659 4501 data2.txt
(out) 30 1524 10400 total
例えばカレントディレクトリにあるファイルの単語数をxargsで数えてみる。tオプションを付けることで、xargsが実際に実行するコマンドを表示している。
解説
xargsは入力をスペース(0x20),タブ文字(0x09),および改行文字(LinuxではLF)で分割し、引数として他のコマンドに渡す。引数の個数によっては複数回に分けてコマンドに渡すこともある。
コマンドラインオプション
オプション | 説明 |
---|---|
-a filename | 入力をファイルから受け取る。 |
-t | 実行するコマンドを表示する。 |
-p | 実行する前にユーザに確認する。自動で-tが有効になる。 |
-0 | 入力をヌル文字区切りとして扱う。 |
-d delimiter | 入力を指定の文字区切りとして扱う。 |
-I replace-str | 引数を展開する場所を指定する。 |
-L max-lines | コマンドに渡す引数の上限数を入力データの行数で指定する。 |
-n max-args | コマンドに渡す引数の上限数を指定する。 |
-P max-procs | 可能なら、プロセスを並列に実行する。(最大並行数はmax-procs) |
-r | 入力が空のとき、コマンドを実行しない。 |
使用例
しばしば他のコマンドの実行結果を、別のコマンドの引数として渡すために用いられる。
$ ls
(out)data1.txt data2.txt
ls | xargs -t -r wc
(out)wc data1.txt data2.txt
(out) 17 865 5899 data1.txt
(out) 13 659 4501 data2.txt
(out) 30 1524 10400 total
ファイルのリストに対してコマンドを実行する
lsの結果やfindの結果のようにストレージ上にあるファイルのリストを取得し、その結果に対してコマンドを実行する場合、findのexecオプションを使う方が良い。その方が空白を含むファイル名などがあった場合に安全である。
空白を含むファイル名に対して、wcを実行する例を示す。xargsはwc data file.txt
というコマンドを実行しており、これはdataとfile.txtの2つの単語数を数えるコマンドと解釈される。
ls
(out)'data file.txt'
ls | xargs -t -r wc
(out)wc data file.txt
(out)wc: data: No such file or directory
(out)wc: file.txt: No such file or directory
(out)0 0 0 total
findであれば、以下のようにすると動作する。
find -type f
(out)./data file.txt
find -mindepth 1 -execdir wc {} \;
(out) 1 6 27 ./data file.txt