次を含むドキュメントをgrepした場合:
ThisExampleString
...式This*String
または*String
の場合、何も返されません。ただし、This*
は上記の行を期待どおりに返します。
式が引用符で囲まれているかどうかは違いません。
アスタリスクは未知の文字をいくつでも示していると思いますか?式の先頭にある場合にのみ機能するのはなぜですか?これが意図された動作である場合、式This*String
および*String
の代わりに何を使用しますか?
正規表現 のアスタリスクは、「前の要素に0回以上一致する」ことを意味します。
grep 'This*String' file.txt
を使用した特定のケースでは、「ちょっと、grep、Word Thi
に一致し、その後に小文字のs
が0回以上続き、その後にWord String
が続きます」と言います。小文字のs
はExample
のどこにも見つからないため、grepはThisExampleString
を無視します。
grep '*String' file.txt
の場合、「grep、空の文字列に一致する-文字通り何もない-Word String
の前に」と言っています。もちろん、それはThisExampleString
の読み取り方法ではありません。 ( 他の考えられる意味 ---E
フラグを使用して、または使用せずにこれを試すことができます-しかし、ここで本当に必要なものはありません。)
.
は「任意の1文字」を意味することがわかっているので、これを行うことができます:grep 'This.*String' file.txt
。これで、grepコマンドはそれを正しく読み取ります。This
の後に任意の文字(ASCII文字の選択と考えてください)を何度でも繰り返し、その後にString
を続けます。
BREの*
メタキャラクター1s、ERE1sおよびPCRE1sは、以前にグループ化されたパターンの0回以上の出現(グループ化されたパターンが*
メタ文字の前にある)、0個以上の前の文字クラスの出現(文字クラスが*
メタ文字の前にある)または0個以上の前の文字の出現(グループ化されたパターンも文字クラスも*
メタ文字の前にない場合);
つまり、This*String
パターンでは、グループ化されたパターンまたは文字クラスが前にない*
メタキャラクターであるため、*
メタキャラクターは、前の文字の0回以上の出現に一致します(この場合、s
文字):
% cat infile
ThisExampleString
ThisString
ThissString
% grep 'This*String' infile
ThisString
ThissString
任意の文字の0回以上の出現に一致させるには、任意の文字に一致する.
メタ文字の0回以上の出現に一致させる必要があります。
% cat infile
ThisExampleString
% grep 'This.*String' infile
ThisExampleString
BREとEREの*
メタキャラクターは常に「貪欲」です。つまり、最長一致に一致します。
% cat infile
ThisExampleStringIsAString
% grep -o 'This.*String' infile
ThisExampleStringIsAString
これは望ましい動作ではない場合があります。そうでない場合は、grep
のPCREエンジンをオンにし(-P
オプションを使用)、?
メタキャラクターを追加します。これは、*
および+
メタキャラクターは、貪欲さを変える効果があります。
% cat infile
ThisExampleStringIsAString
% grep -Po 'This.*?String' infile
ThisExampleString
1:基本的な正規表現、拡張された正規表現、およびPerl互換の正規表現
ここにある説明の1つ link :
アスタリスク「
*
」は、正規表現でワイルドカードと同じことを意味しません。これは、直前の1文字または[0-9]などの式に適用される修飾子です。アスタリスクは、その前のゼロ個以上に一致します。したがって、[A-Z]*
は、なしを含む任意の数の大文字に一致し、[A-Z][A-Z]*
は1つ以上の大文字に一致します。
*
には、シェル グロビング 文字(「ワイルドカード」)と正規表現 メタキャラクター の両方として特別な意味があります。両方を考慮する必要がありますが、 quote 正規表現を使用する場合は、シェルがそれを特別に処理しないようにし、変更せずに grep
に渡すようにすることができます。 sort ofは概念的には似ていますが、*
がシェルにとって意味することは、grep
で意味することとはまったく異なります。
*
をワイルドカードとして扱います。あなたが言った:
式を引用符で囲んでも違いはありません。
これは、コマンドを実行したときにたまたまディレクトリにあるファイルによって異なります。ディレクトリセパレーター/
を含むパターンの場合、システム全体に存在するファイルに依存する場合があります。常に quotegrep
-の正規表現と single quotes が通常最良である必要があります-unlessで大丈夫です 9種類の潜在的に驚くべき変換 シェルは、grep
コマンドを実行する前にbeforeを実行します。
シェルが 引用符付き ではない*
文字を検出すると、「任意の文字の0個以上」を意味するとみなされ、 それを含むWordを置き換えます のリストに置き換えますパターンに一致するファイル名。 (.
で始まるファイル名は除外されます-パターン自体が.
またはで始まる場合を除き、いずれにせよそれらを含めるようにシェルを設定しました。)これは globbing -また、名前filename expansionおよびpathname expansionによっても。
grep
を使用すると、通常、最初の一致するファイル名が正規表現として使用されます。たとえそれがnotが正規表現であることは人間の読者には明らかです。 -一方、グロブから自動的にリストされた他のすべてのファイル名は、一致を検索するファイルinsideとして取得されます。 (リストは表示されません。grep
に不透明に渡されます。)これが起こることはほとんどありません。
これが問題ではないsometimesである理由-そしてあなたの特定のケースでは、少なくともこれまでのところではなかった-それは*
次のすべてに該当する場合:
名前が一致したnoファイルがありました。...またはシェルでグロブを無効にしました。通常はset -f
でまたは同等のset -o noglob
。しかし、これはまれであり、おそらくあなたがそれをやったことを知っているでしょう。
デフォルトの動作では、一致するファイル名がない場合は*
をそのままにするシェルを使用しています。これはBashの場合です。Bashはおそらくを使用していますが、すべてのBourneスタイルのシェルではありません。 (たとえば、人気のあるシェルZshのデフォルトの動作は、グロブが(a)を展開するか、(b)がエラーを生成することです。 )...またはシェルのこの動作を変更しました-実行方法はシェルによって異なります。
一致するファイルがない場合にグロブをnothingに置き換えたり、エラーメッセージで失敗したりするようシェルにそうでない場合この状況。 Bashでは、それぞれnullglob
またはfailglob
シェルオプション を有効にすることで実行できます。
#2と#3に頼ることもできますが、#1に頼ることはめったにありません。引用符で囲まれていないパターンを使用するgrep
コマンドは、異なるファイルがある場合、または別の場所から実行する場合、動作を停止する場合があります。 正規表現を引用すると、問題はなくなります。
grep
コマンドは*
を量指定子として扱います。他の答え- Sergiy Kolodyazhnyyによる および kosによる -なども、この質問のこの側面に多少異なる方法で対処しています。したがって、この回答の残りの部分を読む前または読んだ後に、まだ読んでいない人にそうすることを勧めます。
*
がgrepになったと仮定します-その引用符で確認する必要があります--grep
は、その前の項目 何度でも発生する可能性があります ではなく、一度だけ発生する。まだ一度発生する可能性があります。または、まったく存在しない可能性があります。または、繰り返すことができます。これらの可能性のanyに適合するテキストが一致します。
「アイテム」とはどういう意味ですか?
単一の 文字 。 b
はリテラルb
と一致するため、b*
はゼロ個以上のb
sと一致します。したがって、ab*c
はac
、abc
、abbc
、abbbc
などと一致します。
同様に、 .
は任意の文字と一致します なので、.*
はゼロ個以上の文字と一致します1、したがってa.*c
はac
、akc
、ahjglhdfjkdlgjdfkshlgc
、さらにはacccccchjckhcc
などに一致しますOr
文字クラス 。 [xy]
は、それぞれがx
又はy
、従って[xy]*
マッチx
、y
、pq
、pxq
、pyq
、pxxq
、pxyq
、pyxq
、pyyq
、等のいずれかであるゼロ以上の文字にマッチするp[xy]*q
pxxxq
又はpxxyq
を一致するため.
これは、\w
、\W
、\s
、\S
などの文字クラスの 短縮形 にも適用されます。 \w
はすべてのWord文字と一致するため、\w*
は0個以上のWord文字と一致します。 または
A グループ 。 \(bar\)
はbar
と一致するため、\(bar\)*
は0個以上のbar
sと一致するため、foo\(bar\)*baz
はfoobaz
、foobarbaz
、foobarbarbaz
、foobarbarbarbaz
などと一致します。
-E
または-P
オプションを使用すると、grep
は正規表現を BRE ではなく、それぞれ ERE または PCRE として扱います=、そしてグループは(
)
ではなく\(
\)
で囲まれているため、\(bar\)
の代わりにfoo(bar)baz
とfoo\(bar\)baz
の代わりに(bar)
を使用します。
man grep
は、最後にBREおよびERE構文のわかりやすい説明を提供し、先頭にgrep
が受け入れるすべてのコマンドラインオプションをリストします。リソースとしてそのマニュアルページをお勧めします。また、 GNU Grepドキュメンテーション および このチュートリアル/リファレンスサイト (番号にリンクしています)上のページの)。
grep
をテストおよび学習するには、ファイル名を指定せずにパターンを指定して呼び出すことをお勧めします。次に、端末から入力を受け取ります。行を入力してください。エコーバックされる行は、パターンが一致したテキストを含む行です。終了するには、を押します Ctrl+D 入力の終わりを示す行の先頭。 (または押すことができます Ctrl+C ほとんどのコマンドラインプログラムと同様に。)例えば:
grep 'This.*String'
--color
フラグを使用する場合、grep
は、正規表現に一致した行の特定のpartsを強調表示します。これは、正規表現が何をするのかを見つけたり、検索するものを見つけるのに非常に役立ちますあなたがしたら探しています。デフォルトでは、Ubuntuユーザーは、コマンドラインからgrep
を実行するときに、grep --color=auto
を実行するBashエイリアスを持っています。これは、この目的には十分です。したがって、--color
を手動で渡す必要すらありません。
1したがって、正規表現の.*
は、シェルグロブの*
の意味を意味します。ただし、grep
は、一致anywhereを含む行を自動的に出力するため、正規表現の先頭または末尾に.*
を含める必要はありません。