-exec vs xargs(別名「find | xargs basename」が壊れるのはなぜですか?)


10

特定の種類のすべてのファイルをサブディレクトリに広げようとしていましたが、私の目的のために必要なのはファイル名だけでした。パスコンポーネントを削除してみました basenameしかし、それは動作しませんでした xargs

$ find . -name '*.deb' -print | xargs basename 
basename: extra operand `./pool/main/a/aalib/libaa1_1.4p5-37+b1_i386.deb'
Try `basename --help' for more information.

私はこれらのバリエーションのどちらでも同じこと(全く同じエラー)を得ます:

$ find . -name '*.deb' -print0 | xargs -0 basename 
$ find . -name '*.deb' -print | xargs basename {}

一方、これは期待どおりに機能します。

$ find . -name '*.deb' -exec basename {} \;
foo
bar
baz

これは最新のCygwinとDebian 5.0.3で起こります。私の診断では、xargsは何らかの理由で2つの入力行をbasenameに渡していますが、なぜでしょうか。何が起きてる?

回答:


22

なぜなら basename LOTSではなく、ただ1つのパラメータが必要です。そして xargs たくさんのパラメータを作成します。

あなたの本当の問題を解決するには(ファイル名だけをリストしてください):

 find . -name '*.deb' -printf "%f\n"

これは 'basename'(man find)だけを出力します。

 %f     File's name with any leading directories
        removed (only the last element).

1
おお…… /もう一度額をたたく/ 「ダミーを探す」という本が必要だと思います。
quack quixote

私はその点を考えました xargs それはそれが引数のリストを作成し、後に続くコマンドにそれぞれをフィードするということですか?そうでなければそれとの違いは何ですか find . -name '*.deb' | basename
WindowsMaker

GNUベース名は現在 -a オプション: "複数の引数をサポートし、それぞれを名前として扱う"
bishop

1
@WindowsMaker xargs 変換する stdin コマンド引数ある意味では、それは逆です。 echoこれは、引数を stdout。違いは find ... | xargs -n1 basename または find ... | xargs basename -a そして find ... | basename 前の2つはの実装で動作するということです basename 無視する stdin
8bittree

17

これを試して:

find . -name '*.deb' | xargs -n1 basename

これは説明ではありません、これは回避策です。そしてその回避策は、見つかったファイルに対して-execで 'basename'を呼び出すのと同じくらい良いです。
akira

4
+1 ...これは説明ではありませんが、表示されているxargsスイッチを調べることになります。最終的には、akiraとjohn tの答えを読んだときに使用した額にたたく動作になります。
quack quixote

1
これが私のやり方です。私はすべての内外を学ぶことを気にしません。 find commandなので、ファイルの検索と一覧表示にのみ使用します。それ以外のものにはxargsを使用します。
Ryan Thompson

4

basenameは単一の引数のみを受け入れます。を使う -exec それぞれが正常に機能するため {} 現在処理中のファイル名に置き換えられ、コマンドが1回実行されます。 一致したファイルごと 代わりに、basenameへのすべての引数を一度に送信しようとするのではありません。


2

xargs 引数を1つだけ渡すように強制することもできます。

find . -name '*.deb' -print | xargs -n1 basename

これは動作しますが、受け入れられた答えは使用しています find より適切な方法で。この質問を探しています xargs basename ファイルの場所のリストを取得するために別のコマンドを使用しているため、問題が発生します。の -n1 の旗 xargs 私にとって究極の答えでした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.