スターサインインgrepの使用


90

linux / bashの特定のファイルで部分文字列「abc」を検索しようとしています

私もです:

grep '*abc*' myFile

何も返しません。

しかし、私がそうするなら:

grep 'abc' myFile

正しく一致を返します。

さて、これは私にとって問題ではありません。しかし、もっと複雑な文字列をgrepしたい場合はどうすればよいですか?

*abc * def *

grepを使用してそれをどのように達成しますか?


3
grep自体は、ほとんどのプラットフォームでワイルドカードをサポートしていません。ワイルドカードを使用するには、egrepを使用する必要があります。シェルの構文は異なります。シェルの「*」は<任意の文字列>です。egrepでは、「前のエンティティの多くに0」と言う演算子です。grepでは、これは単なる通常の文字です。
PanCrit 2009

@PanCrit:*grepとegrepで同じことを意味します。これは、先行するアトムの0個以上を意味する数量詞です。これは、シェルで使用されるワイルドカードとはまったく異なる概念です。
アランムーア

回答:


124

アスタリスクは単なる繰り返し演算子ですが、何を繰り返すかを伝える必要があります。/*abc*/abと0個以上のcを含む文字列に一致します(2番目の*がc上にあるため、最初の*は繰り返すものがないため、意味がありません)。何かに一致させたい場合は、言う必要があります.*-ドットは(特定のガイドライン内の)任意の文字を意味します。abcと一致させたい場合は、と言うことができますgrep 'abc' myFile。あなたのより複雑な試合のために、あなたが使用する必要がある.*- grep 'abc.*def' myFileABC間では、必要に応じて何かをデフ続い含む文字列にマッチします。

コメントに基づいて更新:

*正規表現の*は、コンソールの*とまったく同じではありません。コンソールでは、*はglob構造の一部であり、ワイルドカードとして機能します(たとえばls *.log、.logで終わるすべてのファイルを一覧表示します)。ただし、正規表現では、*は修飾子です。つまり、その前の文字またはグループにのみ適用されます。正規表現で*をワイルドカードとして機能させる場合.*は、前述のように使用する必要があります。ドットはワイルドカード文字であり、スターは、ドットを変更するときに1つ以上のドットを見つけることを意味します。すなわち。任意の文字を1つ以上検索します。


1
質問者は、シェルのワイルドカードと正規表現の違いについて混乱していると思います。また、より複雑な式は次のようになると思います:grep'abc。* def '(少なくとも1つのスペースが存在します-おそらく私が書いたように2つ)。
Jonathan Leffler

1
実は、questionnerは「ABC」が「^ ABC $」:-Dと同じものではないことを理解していないようだ
マッサ

1
はい、グロブと完全な正規表現の間で混乱しました。ドットなしの*は、シェル上のすべてのものと一致することを意味します。
Saobi 2009

1
grep*は「0以上」を意味し、grepはデフォルトで貪欲です。なお、grepの中の基本的な正規表現のメタ文字 ?+{|(、及び )その特別な意味を失います。詳細:grep regexps
KrisWebDev

25

ドット文字は、任意の文字に一致することを.*意味するため、任意の文字が0回以上出現することを意味します。おそらく.*、単にではなく使用することを意味します*


ドットは、新しい行を除くすべての文字を受け入れるメタ文字です。
AbhishekKamal20年

12

「星座」は、その前に何かがある場合にのみ意味があります。ツール(この場合はgrep)がない場合は、エラーとして処理される可能性があります。例えば:

'*xyz'    is meaningless
'a*xyz'   means zero or more occurrences of 'a' followed by xyz

5
*は無意味ではありません。(繰り返しの)通常の意味はありませんが、「私はスターです」という意味です。星の後にx、y、zが続く行に一致します。
Jonathan Leffler

2
@Jonathanツールによって異なります。

9

Perlスタイルの正規表現のサポートを有効にするgrep-P-を使用します。

grep -P "abc.*def" myfile

6

たとえばLinuxのシェルコマンドラインで機能する式のように、試した式は「glob」と呼ばれます。Glob式は、完全な正規表現ではありません。これは、grepが検索する文字列を指定するために使用するものです。ここに違いについての(古い、小さな)投稿があります。glob式( "ls *"のように)はシェル自体によって解釈されます。

グロブからREに変換することは可能ですが、通常は頭の中で行う必要があります。


1
シェルによって解析された場合、それはグロブにすぎません。彼は検索文字列を一重引用符で囲んで保存しているため、シェルは文字列をそのままにして、argvでそのままgrepに渡します。
目立つコンパイラ

4

正規表現を使用していないため、選択するgrepバリアントはfgrep、である必要があります。これは、期待どおりに動作します。


2
fgrep現在は非推奨ですgrep -f。代わりに使用する必要があります。
プロメテウス

1
それが「grep-F」です。古き良きfgrepは「非推奨」になる可能性がありますが、私がまだ生きている間は、fgrepが削除されることはありません。
AndrewBeals18年


1

これはあなたが探している答えかもしれません:

grep abc MyFile | grep def

唯一のことは...「def」が「abc」の前または後にある行を出力します


1

これは私のために働いた:

grep "。* $ {expr}"-ドットが前に付いた二重引用符。ここで、「expr」は行末に必要な文字列です。

追加のスイッチがない標準のUNIXgrep。


0

「*」は前の項目の修飾子として機能します。したがって、「abc * def」は「ab」の後に0個以上の「c」が続き「def」が続くものを検索します。

おそらく必要なのは、「abc。* def」で、「abc」の後に任意の数の文字が続き、その後に「def」が続きます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.