私の理解から、以下はまったく同じことを意味するはずです:
ls -1 | xargs file {}
ls -1 | xargs -I{} file {}
-Iオプションを指定しない場合、デフォルトで-I {}になります。
現在のディレクトリにあるすべてのファイルを一覧表示し、それぞれに対してfile
コマンドを実行したいと思います。名前にスペースがあるものもあります。しかし、私は違いに気づきました。下記参照:
$ ls -1
Hello World
$ ls -1 | xargs file {}
{}: ERROR: cannot open `{}' (No such file or directory)
Hello: ERROR: cannot open `Hello' (No such file or directory)
World: ERROR: cannot open `World' (No such file or directory)
$ ls -1 | xargs -I{} file {}
Hello World: directory
-I {}を明示的に指定すると、ファイル名の空白は期待どおりに扱われます。
-I
には、定義済みのプレースホルダーが必要です。 -i
オプションは、{}
がプレースホルダーであると想定します。これが、少なくともCygwinとCentOSでman xargs
の{}の仮定を見つけた場所です。
どちらのオプションも指定せずに呼び出されたxargsはプレースホルダーを必要とせず、引数の最後にSTDINを追加するだけです。
echo
を例に追加して、xargsが何をしているのかを確認してください:
$ ls -1
Hello World/
あなたの誤った例では{}
を使用しています:
$ ls -1 | xargs echo file {}
file {} Hello World/
したがって、file
cmdは{} Hello World
の引数とエラーを確認します。
Xargs呼び出しで明示的に{}
を使用する場合:
$ ls -1 | xargs -i echo file {}
file Hello World/
またはプレースホルダーなし:
$ ls -1 | xargs echo file
file Hello World/
上記で呼び出されたxargsは{}を必要としません。 STDINをプレースホルダーなしでコマンドの最後に追加します。 {}の使用は通常、次のように、コマンドの途中のどこかでSTDINを実行することを意味します。
$ ls -1 | xargs -i mv {} /path/to/someplace/.