
ワイルドカード "*"を使用してすべての.txtファイルをgrepしたいと思います。
このコマンドを試しましたが(引用符 ""なしで)失敗しました。
ls | grep "*.txt"
興味深いことに、ディレクトリの.txtファイルに対応するgrepコマンドに別の文字を入れると機能します。
>>ls | grep s*.txt
sample.txt
私はこれがうまくいくls *.txt
ことを知っていましたが、grepコマンドの特性に少し驚きました。なぜこれが起こるのを助けることができる人がいますか?
grepが正規表現を使用するためですか?助けてください。
答え1
正規表現では、*
シェルモードのように「任意の文字数」ではなく、「前の項目の数」を意味します。 「すべての単一文字」を意味します.
。したがって、「テキストに続くすべてのもの.txt
」を見つけるには.*\.txt
。\.txt
その後、最後に来る必要はないので、同様の\.txt
ファイル名も一致します。パターンを行末までロックする必要があります。foo.txtgz
.txt
\.txt$
正規表現は、*.txt
実装とデフォルトの正規表現(grep
)または拡張正規表現(grep -E
)を使用しているかどうかに応じて、意味がないか、間違っているか、文字通りアスタリスクを探します。使用しないことをお勧めします。
一方、「文字数、単一文字、リテラル」s*.txt
を探します。これはより効率的な正規表現ですが...まだ一致しません。s
txt
sample.txt
代わりに、2番目のコマンドでは引用されていないため、s*.txt
シェルはそれを見る前にs*.txt
拡張します。grep
一致する唯一のファイルがある場合は、その出力でsample.txt
そのgrep
ファイルを見つけますls
。 (一致するファイル名が複数ある場合、最初のファイルはパターンとして扱われ、残りはファイル名として読み込まれますgrep
。この場合、パイプの入力は無視されます。)
ただし、ls
ファイルのリストを取得することも可能なので、次のものを使用できます。
ls | grep '\.txt'
ファイルを入手するには.txt
使いやすくなります。
ls *.txt
代わりに。
答え2
そのうちのいくつかは正規表現を使用したからですgrep
(実際のre
名前が意味するのはこれです。Gグローバルアル字型定期的な金利表現する血印刷)。
正規表現のワイルドカード文字は、*
シェルワイルドカードのワイルドカード文字とは異なります。*
正規表現では、*
「0個以上の以前に定義されたオブジェクト」を意味します。しかし.
それは返品「文字」を意味するワイルドカードです。
Shell globとは*
「0個以上の文字」を意味します。 .
まったくワイルドカードではありません。
grep
パターンを検索するときは、"*.txt"
ゼロ個以上の項目を探し、その後に文字、最後にリテラル文字列を探しますtxt
。
grep
パターン"s*.txt"m you are looking for a literal
s txt`, followed by zero or more
を使用する場合s, followed by any character, followed by the literal string
。
そのため、正規表現でよく見られるのは、.*
「すべての文字の1つの後に0個以上の文字が続くもの」を意味するということです。正規表現は「実際にはゼロ文字を除くすべての文字の組み合わせ」です。
ls *.txt
シェルに「グローブパターンと一致するファイル名を探してください」と指示するときは、ここにリストしてコマンドの*.txt
引数として指定してください。ls
答え3
grepがファイルを検索していることに注意してください。コンテンツ最初のパラメータは検索モードであり、他のパラメータはボールファイルとして解釈されます。
フラグを使用するか、それをスクリプトgrep -H -o
に入れて実行して、引数として渡される前にシェルグローブがどのように拡張されるかを確認すると、より明確になります。grep
bash -x script