回答:
最初に、シェルによる拡張からパターンを保護する必要があります。最も簡単な方法は、単一引用符で囲むことです。単一引用符は、それらの間の何か(バックスラッシュを含む)の展開を防ぎます。できないのは、パターン内に単一引用符を付けることだけです。
grep 'foo*' *.txt
単一引用符が必要な場合は、'\''
(終了文字列リテラル、リテラル引用、オープン文字列リテラル)と書くことができます。
grep 'foo*'\''bar' *.txt
次に、grepはパターンの2つの構文をサポートします。古いデフォルトの構文(基本的な正規表現)は代替(|
)演算子をサポートしていませんが、一部のバージョンでは拡張機能として使用されていますが、バックスラッシュで記述されています。
grep 'foo\|bar' *.txt
移植可能な方法は、新しい構文である拡張正規表現を使用することです。-E
オプションを渡して選択する必要がありますgrep
。Linuxでは、egrep
代わりに入力することもできますgrep -E
(他の大学では、エイリアスにすることができます)。
grep -E 'foo|bar' *.txt
(選言を使用して複雑なパターンを構築するのではなく)いくつかのパターンのいずれかを探している場合の別の可能性は、複数のパターンをに渡すことgrep
です。これを行うには、各パターンの前に-e
オプションを付けます。
grep -e foo -e bar *.txt
fgrep
やgrep -F
、小さなパターンのための違いは無視できる程度になりますが、彼らは長くなるとして、メリットは...表示するために開始
grep -F
実際のパフォーマンス上の利点があるかどうかは、grepの実装に依存します。それらのいくつかは、とにかく同じアルゴリズムを適用します-F
。-F
たとえば、GNU grepはで高速ではありません(grep -F
マルチバイトロケールで低速になるバグもあります。同じ定数パターンgrep
は実際にはかなり高速です!)。一方、BusyBoxのgrepは-F
、大きなファイルから多くのメリットを得ることができます。
egrep
predatesに注意してくださいgrep -E
。GNU固有ではありません(Linuxとはまったく関係ありません)。実際には、デフォルトがgrep
まだサポートしていないSolarisのようなシステムがまだあります-E
。
egrep "foo|bar" *.txt
または
grep "foo\|bar" *.txt
grep -E "foo|bar" *.txt
gnu-grepのmanページを選択的に引用:
-E, --extended-regexp
Interpret PATTERN as an extended regular expression (ERE, see below). (-E is specified by POSIX.)
Matching Control
-e PATTERN, --regexp=PATTERN
Use PATTERN as the pattern. This can be used to specify multiple search patterns, or to protect a pattern
beginning with a hyphen (-). (-e is specified by POSIX.)
(...)
grep understands two different versions of regular expression syntax: “basic” and “extended.” In GNU grep, there
is no difference in available functionality using either syntax. In other implementations, basic regular
expressions are less powerful. The following description applies to extended regular expressions; differences for
basic regular expressions are summarized afterwards.
最初はこれ以上読みませんでしたので、微妙な違いを認識しませんでした。
Basic vs Extended Regular Expressions
In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose their special meaning; instead use the
backslashed versions \?, \+, \{, \|, \(, and \).
例から学んだので、私は常にegrepと不必要に括弧を使用しました。今、私は何か新しいことを学びました。:)
TC1が言った-F
ように、使用可能なオプションのようです:
$> cat text
some text
foo
another text
bar
end of file
$> patterns="foo
bar"
$> grep -F "${patterns}" text
foo
bar
正規表現が必要ない場合は、次のように、fgrep
またはgrep -F
複数の-eパラメーターを使用する方がはるかに高速です。
fgrep -efoo -ebar *.txt
fgrep
(代替grep -F
)は、正規表現ではなく固定文字列を検索するため、通常のgrepよりもはるかに高速です。
fgrep
されている非推奨のコメントも参照してください。
複数のパターンをgrepする安価で陽気な方法:
$ echo "foo" > ewq ; echo "bar" >> ewq ; grep -H -f ewq *.txt ; rm ewq
-f
オプションが複数のパターンを持つファイルを取るということです。一時ファイル(後で削除するのを忘れることがあります)を作成する代わりに、シェルのプロセス置換を使用するだけです:grep -f <(echo foo; echo bar) *.txt
パイプ(|
)は特殊なシェル文字であるため、エスケープ(\|
)するか、マニュアルに従って引用符で囲む必要があります(man bash
)。
引用は、シェルに対して特定の文字または単語の特別な意味を削除するために使用されます。特殊文字の特別な処理を無効にし、予約語がそのように認識されるのを防ぎ、パラメータの拡張を防ぐために使用できます。
文字を二重引用符で囲むと、引用符内のすべての文字のリテラル値が保持されます
引用符で囲まれていないバックスラッシュ(
\
)はエスケープ文字です。
以下にいくつかの例を示します(まだ言及されていないツールを使用):
を使用してripgrep
:
rg "foo|bar" *.txt
rg -e foo -e bar *.txt
を使用してgit grep
:
git grep --no-index -e foo --or -e bar
注:--and
、などのブール式もサポート--or
してい--not
ます。
行ごとのAND演算については、複数のANDパターンでgrepを実行する方法をご覧ください。
ファイルごとのAND演算については、次を参照してください。ファイルに存在する複数の文字列または正規表現をすべて確認する方法
日付が愚かにフォーマットされたアクセスログがありました:[30 / Jun / 2013:08:00:45 +0200]
しかし、次のように表示する必要がありました:30 / Jun / 2013 08:00:45
問題は、grepステートメントで「OR」を使用すると、2つの別々の行で2つの一致式を受け取っていたことです。
解決策は次のとおりです。
grep -in myURL_of_interest *access.log | \
grep -Eo '(\b[[:digit:]]{2}/[[:upper:]][[:lower:]]{2}/[[:digit:]]{4}|[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}\b)' \
| paste - - -d" " > MyAccess.log
TL; DR:複数のパターンのいずれかに一致した後、さらに処理を行う場合は、次のように囲みます \(pattern1\|pattern2\)
例:「date」という名前を含む変数がStringまたはintとして定義されているすべての場所を検索したい。(例: "int cronDate ="または "String textFormattedDateStamp ="):
cat myfile | grep '\(int\|String\) [a-zA-Z_]*date[a-zA-Z_]* ='
を使用grep -E
すると、括弧やパイプをエスケープする必要がありません。つまり、grep -E '(int|String) [a-zA-Z_]*date[a-zA-Z_]* ='
これは私のために働く
root@gateway:/home/sshuser# aws ec2 describe-instances --instance-ids i-2db0459d |grep 'STATE\|TAG'
**STATE** 80 stopped
**STATE**REASON Client.UserInitiatedShutdown Client.UserInitiatedShutdown: User initiated shutdown
**TAGS** Name Magento-Testing root@gateway:/home/sshuser#
これを行うには複数の方法があります。
grep 'foo\|bar' *.txt
egrep 'foo|bar' *.txt
find . -maxdepth 1 -type f -name "*.txt" | xargs grep 'foo\|bar'
find . -maxdepth 1 -type f -name "*.txt" | xargs egrep 'foo|bar'
3番目と4番目のオプションは、ファイルでのみgrepを実行.txt
し、名前にディレクトリが含まれないようにします。
したがって、ユースケースに従って、上記のオプションのいずれかを使用できます。
ありがとう!!
@geekosaurの答えに追加するには、タブとスペースも含む複数のパターンがある場合は、次のコマンドを使用します
grep -E "foo[[:blank:]]|bar[[:blank:]]"
where [[:blank:]]
は、スペースまたはタブ文字を表すRE文字クラスです