lect1.txt
、lect2.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
.
txt
lect1-txt
lect1xtxt
"lect.*"
2番目の例では、シェルが拡張せずにそのまま渡されるように引用符を入れますgrep
。パターンを引数として渡すだけで、渡されたgrep
ファイル名stdin
からパターンを検索できます。 。
答え2
find *.txt | grep lect*
find(1)
通常、ファイル名ではなくパス名を最初の引数として指定したいと思います。確かにファイル名パターンではありません。シェルは、*.txt
呼び出す前に現在のディレクトリにあるすべてのファイルの名前に拡張しますが、これは望むものではありません。*.txt
find
このコマンドのより有用な変形は次のとおりです。
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
)。 lec
grepping は、途中で、などがlect
あるlectt
文字と一致するすべての項目を印刷します。lecttttttt
しかし、最初の例では、grepがそう遠くまで行くこともありません。シェルパターンを展開して、実際に一致するものを探しています。echo lect*
ディレクトリに適切に拡張されたファイルがありますが、目的の操作を実行していないため、予期せず動作する可能性があります。
私はあなたが欲しいものを提案します:
find . -name 'lect*.txt' -print