find と grep パイプは何も返しません。

find と grep パイプは何も返しません。

lect1.txtlect2.docおよびというファイルがありますlect3.doc

.txt私はファイルであり、ファイル名を含むファイルを取得したいと思いますlect

頑張った

find *.txt | grep lect*

何も返しません。

しかし、私がするとき

find *.txt | grep "lect*"

帰ってきたlect1.txt

これら2つの表現の違いは何ですか?

答え1

grep最初の引数(パターン)に対してコマンドラインに渡されたファイルの検索または stdinファイルが通過しない場合。

引用符がない場合、シェルはlect*次のディレクトリに展開されますlect

grep lect1.txt lect2.doc lect3.doc

意味はlect1.txt.doc両方のファイルからテキストを検索する。ファイルのいずれかに対応するフレーズが含まれていない場合は.doc何も返されません。より正確には、()の後に続くすべての文字をlect1.txt見つけるので、なども探します。)lect1.txtlect1-txtlect1xtxt

"lect.*"2番目の例では、シェルが拡張せずにそのまま渡されるように引用符を入れますgrep。パターンを引数として渡すだけで、渡されたgrepファイル名stdinからパターンを検索できます。 。

答え2

find *.txt | grep lect*

find(1)通常、ファイル名ではなくパス名を最初の引数として指定したいと思います。確かにファイル名パターンではありません。シェルは、*.txt呼び出す前に現在のディレクトリにあるすべてのファイルの名前に拡張しますが、これは望むものではありません。*.txtfind

このコマンドのより有用な変形は次のとおりです。

find . -name 'lect*' | grep 'txt$'

または

find . -name 'lect*txt'

find(1)また、ご利用にご注意ください。グローバル表現使用-name中は基本的にgrep(1)一般的な表現。これは*両方のシステムで異なる意味を持つため、ここで重要です。

BSDとGNUの実装には、正規表現を使用できるfind非標準の基本実装があります。-regex

find . -regex '.*/lect.*txt'

このパターンは次のように使用する必要があります。みんなパスが見つかったので、findプレフィックスが必要で、使用する.*/ように最後まで固定する必要はありませんtxt$grep

答え3

あなたはそれを誤用し、find誤って動作しました。次を実行すると、次のことがわかります。

find *.txt 

あなたは何ですか実際に実行中の作業は次のとおりです。

find lect1.txt

そしてあなたが達成したことはecho。ただし、検索条件を使用して find を実行する場合 (例:

find . -name '*.txt'

次に、現在のディレクトリを繰り返して、.仕様に一致するサブディレクトリのファイル名を印刷します。

*ただし、 '*'はfind、シェル、正規表現*で異なるように解釈されるため、注意する必要があります。

grepあなたのingが*「前の文字のゼロ個以上のインスタンス」を意味する場合。

だからあなたは実際に:

  • すべてのファイル名をエコーし​​ます(globbing *.txt)。
  • lecgrepping は、途中で、などがlectあるlectt文字と一致するすべての項目を印刷します。lecttttttt

しかし、最初の例では、grepがそう遠くまで行くこともありません。シェルパターンを展開して、実際に一致するものを探しています。echo lect*ディレクトリに適切に拡張されたファイルがありますが、目的の操作を実行していないため、予期せず動作する可能性があります。

私はあなたが欲しいものを提案します:

find . -name 'lect*.txt' -print

関連情報