先頭にファイルすると再帰的でないことがわかります


8

ソースツリーを想像してみてください。どこにでもxmlファイルがあります。

しかし、このツリーのルートにXYZ.xmlがあるため、xmlファイルが見つかりません。

find -iname *.xml

戻り値

./XYZ.xml

の代わりに

./XYZ.xml
./a/b/c/bob.xml
./b/d/top.xml

1
From man find:もちろんパターンを引用する必要があることに注意してください。そうしないと、シェルがそれらのワイルドカード文字を展開します。
artdanil 2012年

回答:


18
find -iname '*.xml'

そうでない場合、シェルはに展開さ*.xmlXYZ.xml、実際に実行されるコマンドは

find -iname XYZ.xml

現在のディレクトリにXMLファイルがない場合に機能する理由は、シェルは通常、一致するものがない場合、ワイルドカードを展開しないでおくためです。一般的に、あなたはワイルドカードはシェル以外のプログラムによって拡張することにしたい任意の時間(例えばによってfindtarscp、など)あなたはシェルがそれら自体を拡大しようとはしませんので、それらを引用する必要があります。


1
Thx、それはとても簡単ですが、私は何ヶ月もそれを回避する方法を考えていました。私はそれが本当に奇妙で、非常に一貫性のない振る舞いであることがわかりましたが、今ではそれが見つからないので理解しましたが、bashのせいです。
Olivier Toupin、

2
これはbashの「障害」そのものではなく、引数として渡したいワイルドカードを引用しないことによるものです。これは、シェル入力を受け入れるすべてのプログラムに当てはまります。シェルは、引用符またはエスケープされていない限り、それらをグロブとして展開します。
カレブ

1
Olivierがの問題であり、の問題でbashはないという意味でそれを意味していたと思いfindます。
ユーザー不明

6

次のように引数を引用する必要があります。

find ./ -name '*.xml'

シェルによって展開されるのではなく、findに渡されてから、展開されたバージョンとしてfindに渡されます。


1
OK、*.xml現在のディレクトリに一致しない場合、文字通り渡されます。それが、他のケースでも機能する理由です。非常に役立つ答え。
Eric Wilson

1

ワイルドカードは、コマンドではなくシェルによって展開されます。findシェルに似たワイルドカードマッチングを実行する数少ないコマンドの1つです。

を実行するとls *.xml、最初にシェル*.xmlが一致するファイルのリスト(たとえばfile1.xml file2.xml file3.xml)に展開され、次にシェルはls結果の引数のリストを使用して呼び出しますfile1.xml file2.xml file3.xml。そのため、ファイルについて何echo *.xmlecho知らず、引数がファイル名であるかどうかを気にしなくても、で同じファイル名のリストが表示されます。

実行するとfind . -name "*.xml"

  1. シェルはコマンドラインを解析して特殊文字を認識し、それを単語と句読点に分割します。ここでは単語のリストだけがありますfind.-name、引用されているが。が引用されているので、シェルに関する限り、これは普通の文字です。*.xml**
  2. シェルはコマンドを実行しfind、引数の指定されたリストに:.-name*.xml
  3. find*.xml現在のディレクトリの下の任意のディレクトリで、パターンに一致する名前のファイルを検索します。

実行find . -name *.xmlして一致するファイルがない場合*.xml

  1. シェルはコマンドラインを解析して特殊文字を認識し、それを単語と句読点に分割します。ここでは単語のリストだけがありますfind.-name、引用されていませんが。*.xml*
  2. 単語*.xmlには引用符で囲まれていないワイルドカード文字が含まれているため、シェルはファイル名の生成を実行します。一致するファイル名がないため、パターンは拡張されません。
  3. シェルはコマンドを実行しfindている引数の結果リスト、と.-name*.xml
  4. find*.xml現在のディレクトリの下の任意のディレクトリで、パターンに一致する名前のファイルを検索します。

実行するfind . -name *.xmlと、現在のディレクトリにfile1.xmlfile2.xmlおよびが含まれますfile3.xml

  1. シェルはコマンドラインを解析して特殊文字を認識し、それを単語と句読点に分割します。ここでは単語のリストだけがありますfind.-name、引用されていませんが。*.xml*
  2. 単語*.xmlには引用符で囲まれていないワイルドカード文字が含まれているため、シェルはファイル名の生成を実行します。これ*.xmlは、一致するファイル名のリストに置き換えられます。
  3. シェルはコマンドを実行しfindている引数の結果リスト、と.-namefile1.xmlfile2.xmlfile3.xml
  4. findに達すると、構文エラーについて文句を言いますfile2.xml

を実行find . -name *.xmlし、現在のディレクトリに一致するファイルが1つ含まれている場合file.xml

  1. シェルはコマンドラインを解析して特殊文字を認識し、それを単語と句読点に分割します。ここでは単語のリストだけがありますfind.-name、引用されていませんが。*.xml*
  2. 単語*.xmlには引用符で囲まれていないワイルドカード文字が含まれているため、シェルはファイル名の生成を実行します。これ*.xmlは、一致するファイル名のリストに置き換えられます。
  3. シェルはコマンドを実行しfindている引数の結果リスト、と.-namefile.xml
  4. find完全に有効なコマンドがfind表示されますが、おそらく意図したものではありません。file.xmlファイルの一致を探すのではなく、任意のディレクトリで呼び出されたファイルを探すように指示されます*.xml

(シェルの評価と拡張には他にも多くの機能があります。ここでは、関連する機能のみを説明しました。)

(私が説明するのは、最も一般的なシェルのデフォルトの動作です:sh、bash、dash、ksh、...リスト。これらはどれもここでは役に立ちません。)


-1

これはSolaris 10で機能します。

find /directory-to-search/* -prune -name "*gz"


これは、末尾が.xml。の名前を検索しません。
クサラナンダ

-2

してみてください:

find ./ -name *.xml

私はそれを試しました、同じ結果。
Eric Wilson

私はそれを試しました、そしてそれはうまくいきます。GNU bash 4.2.8の場合
bbaja42

3
これは、グロブが現在のディレクトリのいずれかに一致する場合は機能しません。それは間違った構文です!*常に引用されたかを見つけるためにそれを渡すようにエスケープする必要があります。
カレブ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.