grep
を完全に理解していないのか、正規表現が問題の原因であるのかわからないので、2つの質問があります。 test.txt
という名前の簡単なテストファイルがあります。内容は次のとおりです。
$ cat test.txt Settings.xml blah Settings_1.xml blah Settings_2.xml
次のコマンドを使用して、上記のテストファイルのみを含むディレクトリでgrep
を実行すると、一致するものが返されません。
$ grep -ir "Settings*xml"
1)ワイルドカード*
がピリオドをキャッチしないのはなぜですか?
そして、grep
をそのように実行すると:
$ grep -ir "Settings*.xml"
唯一の違いはワイルドカードの後のピリオドであり、結果は次のとおりです。
test.txt:Settings.xml
2)grep
が他の2つの一致を見つけられないのはなぜですか?
その理由は、*
は正規表現の特殊文字であり、zero or more preceding characters
を意味するためです。 *
をエスケープして、*
を含むリテラル\
文字を意味する必要があります。だからあなたの例では:
grep -ir "Settings*xml"
Setting
で始まり、0個以上のs
文字と最後にxml
がある文字列を検索します。 xml
の前には常に.
が付いているため、ファイルにはそのような文字列はありません。この:
grep -ir "Settings*.xml"
Setting
で始まり、0個以上のs
と.xml
が0個以上のs
文字の後にある文字列を検索します。
最初の正規表現は次のようなものに一致します。
Settingssxml
この他の答え 何が起こったのかを説明し、あなたの明確な質問に答えます。私の答えは、より広い文脈を紹介することを目的としています。
*
は0文字以上(任意の文字)に一致し、.
は文字通り.
を意味すると予想したと思います。これはシェルグロブで機能します。つまり、次のようなファイルがある場合です。
$ ls -1
Settings.xml
blah
Settings_1.xml
Settings_2.xml
次に(たとえば、bash
で)次のことができます。
$ echo Settings*.xml
Settings.xml Settings_1.xml Settings_2.xml
grep
が正規表現構文を使用しているため、期待したものが得られませんでした。
.
は(ほぼ)すべての文字に一致します。*
は、「0個以上の先行文字」を意味します。\
は、次の文字を文字どおりに解釈するように強制します。そのため、"Settings*.xml"
の代わりに"Settings.*\.xml"
を使用する必要がありました。この場合:
.*
は、*
が行うと思ったことを実行します。\.
は、.
が行うと思っていたことを実行します。