web-dev-qa-db-ja.com

xargs -I replace-strオプションの違い

私の理解から、以下はまったく同じことを意味するはずです:

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 {}を明示的に指定すると、ファイル名の空白は期待どおりに扱われます。

16
foresightyj

-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/.
21
johnnyB