Linuxコマンド xargs(引数を標準入力から与えて実行する)

コマンドを実行した結果(lsの結果やfindによる検索結果など)を、コマンドラインの文字数上限を超えないように引数を生成し、指定したコマンドに渡して実行するコマンドについて解説。

RHEL Fedora CentOS Vine Deblan Ubuntu Plamo

参考サイト:Man page of INSTALL

概要・使用方法

空白もしくは改行で区切られた文字列を標準入力から読み、1行ずつに引数として渡して実行します。コマンドを指定しない場合、文字列はechoに送られます。xargsへの入力は指定したコマンドへの引数として渡されます。

コマンドラインには「getconf ARG_MAX」で取得できるように文字数には上限があります。例えば、ls * | rm を実行した際、作業ディレクトリのすべてのファイル名文字数が上限を超えるとrmを正常に実行できませんが、ls * | xargs rm とすると、複数のrmを実行するのでその上限には達しません。つまりは、xagsコマンドはコマンドに渡す引数を上限を超えないように加味してくれるコマンドとなる。

書式

$ xags [オプション] [コマンド[引数]]

オプション

-a
–arg-file=ファイル名
標準入力ではなくファイルから読み込む
-0
–null
区切り文字をNULL文字にします。ファイル名のように引数自体に空白文字が
含まれる場合にしようします。findコマンドの-print0処理と合わせて使うことが多い。
-d 区切り文字
–delimiter=区切り文字
区切り文字を指定した文字にします。シェルが解釈する文字は”””で囲むか
エスケープします。
-E 文字列指定した文字列を終端文字列として扱う
-I 文字列xargs内のコマンド引数中の指定文字列を、入力文字列に置き換える
-L 行数最大-Lで指定した行読み込むごとにコマンドを実行します。
-n 引数の数,
–max-args=引数の数
最大-nで指定した個の引数を読み込むごとにコマンドを実行します。
-p,
–interactive
コマンドごとに実行を問い合わせる
-s 文字数,
–max-chars=文字数
コマンド名を含めてコマンドラインが最大〇バイトになるように実行する。
-t,
–vebose
実行する前にコマンドラインを標準エラー出力に出力する
-x,
–exit
コマンドラインが-Sオプションのコマンドライン上限文字数を過ぎていたら終了する
-p 数,
–max-procs=数
同時に実行する最多プロセス数を指定する
(デフォルトは1、0を指定するとできる限り実行する)
オプション一覧表

サンプル

カレントディレクトリにsample1.txt~sample8.txtの計8つのファイルがあります。xargs -nを使用して、1回のコマンドに渡す引数の数を5つに限定して実行してみます。lsで返されたファイルを名を空白で区切って、上限5個までの引数にしてコマンドに渡しています。

つまり、以下のサンプルではxargsに実行するコマンドを指定した場合、計2回実行されることになります。

$ ls |xargs -n 5

実行結果

[centos@xxx work]$ ls -l
total 32
-rw-rw-r-- 1 centos centos 6 Apr  5 21:28 sample1.txt
-rw-rw-r-- 1 centos centos 6 Apr 26 21:31 sample2.txt
-rw-rw-r-- 1 centos centos 6 Apr 26 21:31 sample3.txt
-rw-rw-r-- 1 centos centos 6 Apr 26 21:31 sample4.txt
-rw-rw-r-- 1 centos centos 6 Apr 26 21:31 sample5.txt
-rw-rw-r-- 1 centos centos 6 Apr 26 21:31 sample6.txt
-rw-rw-r-- 1 centos centos 6 Apr 26 21:31 sample7.txt
-rw-rw-r-- 1 centos centos 6 Apr 26 21:31 sample8.txt

[centos@xxx work]$ ls |xargs -n 5
sample1.txt sample2.txt sample3.txt sample4.txt sample5.txt
sample6.txt sample7.txt sample8.txt
[centos@xxx work]$ 

カレントファイルの削除する

findでカレントにあるファイルを検索し検索結果をxargsコマンドに渡しrmで削除する。

サンプル

$ find ./ -type f | xargs rm

実行結果

[centos@xxx work]$ find ./ -type f
./sample1/sample2.txt
./sample1/sample1.txt
./work.txt
./sample.tgz
./find_result.txt
[centos@xxx work]$ find ./ -type f | xargs rm
[centos@xxx work]$ find ./ -type f

数日以上修正されていないファイルを削除する

findで5日以上修正されていないファイルを検索し検索結果をxargsコマンドに渡しrmで削除する。

サンプル

$ find /tmp / -type f -mtime -5 | xargs rm

実行結果

[root@xxx centos]$  find /tmp/ -type f -mtime -5
/tmp/hsperfdata_confluence/1371
/tmp/hsperfdata_tomcat/999
/tmp/work/sample/sub_sample/sample1.txt
/tmp/work/sample/top.txt
[root@xxx centos]$  find /tmp/ -type f -mtime -5 | xargs rm
[root@xxx centos]$  find /tmp/ -type f -mtime -5
[root@xxx centos]$ 

空白を含むディレクトリ以下のファイルを扱う

ディレクトリに空白が含まれている場合は、エラーとなってしまうためfindの出力をNULL文字区切りにし、xargsでもNULL文字扱いにする。

サンプル

$ find . -name "sample.txt" -print0 | xargs -0 ls -l

実行結果

[centos@xxx work]$ tree
.
├── Program\ Files
│   └── sample.txt
└── Program_Files
    └── sample.txt

2 directories, 2 files

[centos@xxx work]$ find . -name "sample.txt" | xargs ls -l
ls: cannot access ./Program: No such file or directory
ls: cannot access Files/sample.txt: No such file or directory
-rw-rw-r-- 1 centos centos 6 Apr 26 02:42 ./Program_Files/sample.txt

[centos@xxx work]$ find . -name "sample.txt" -print0 | xargs -0 ls -l
-rw-rw-r-- 1 centos centos 4 Apr 26 02:42 ./Program Files/sample.txt
-rw-rw-r-- 1 centos centos 6 Apr 26 02:42 ./Program_Files/sample.txt
[centos@xxx work]$