web-dev-qa-db-ja.com

grepとドル記号のエスケープ

文字列$Id$が含まれるファイルを知りたい。

grep \$Id\$  my_dir/mylist_of_files

0回出現します。

私は使用しなければならないことを発見しました

grep \$Id$ my_dir/mylist_of_files

次に、$Idが出力で色付けされている、つまり一致していることがわかります。

2番目の$を一致させる方法と、\$Id\$が機能しない理由.

2番目の$が最後の文字であるかどうかは関係ありません。

私はgrep 2.9を使用しています。


質問を投稿する前に、Googleを使用しました...

答えを見つけました

Test2という名前のファイルで$(ドル記号)を検索するには、次のように入力します。

grep \\ $ test2

シェルが\ $(単一の円記号、ドル記号)をgrepコマンドに渡すように強制するには、\\(二重の円記号)文字が必要です。 \(単一のバックスラッシュ)文字は、grepコマンドに次の文字(この例では$)を式文字ではなくリテラル文字として扱うように指示します。 fgrepコマンドを使用して、バックスラッシュなどのエスケープ文字を使用する必要をなくします。

grep \$Idが機能する理由とgrep \\$Id\\$が機能しない理由がわかりません。

少し混乱しています...

33
Luc M

ここには2つの別々の問題があります。

  1. grepBasic Regular Expressions (BRE)を使用し、$はBREの特殊文字で、式の最後にのみあります。この結果、$内の$Id$の2つのインスタンスが等しくなくなります。最初の文字は通常の文字で、2番目の文字は行の終わりに一致するアンカーです。 2番目の$をリテラル$に一致させるには、バックスラッシュでエスケープする必要があります(つまり、$Id\$)。最初の$をエスケープすることもできます:\$Id\$。一貫性があるように見えるので、これを使用します。¹

  2. ここで機能している完全に無関係な2つのエスケープ/引用メカニズムがあります。シェル引用と正規表現のバックスラッシュ引用です。問題は、正規表現が使用する多くの文字がシェルにも特殊であり、その上に、正規表現のエスケープ文字であるバックスラッシュがシェルの引用文字でもあることです。これが、二重のバックスラッシュを含む混乱を頻繁に目にする理由ですが、あまり読みにくいため、シェルの正規表現の引用にバックスラッシュを使用することはお勧めしません。

    代わりに、これを行う最も簡単な方法は、'regex'のように、最初に正規表現全体を一重引用符で囲むことです。一重引用符はシェルが持つ最も強力な引用形式です。正規表現に一重引用符が含まれていない限り、シェル引用を心配する必要がなくなり、純粋なBRE構文に集中できます。

したがって、これを元の例に適用して、正しい引用符(\$Id\$)を一重引用符で囲みます。以下はあなたが望むことをするはずです:

grep '\$Id\$' my_dir/my_file

\$Id\$が機能しない理由は、シェル引用の削除(シェル引用のより正確な言い方)が適用された後、grepが参照する正規表現が$Id$であるためです。 (1.)で説明したように、この正規表現は、最初の$Idがリテラルで、2番目が特殊なアンカー文字であるため、行の最後でのみリテラル$と一致します。

Extended拡張正規表現(ERE)に切り替えた場合も注意してください。 egrep(またはgrep -E)を使用することにした場合、$文字は常に特殊です。 EREでは、$Id$は文字に一致しないため、何にも一致しませんafter行末なので、\$Id\$が唯一の方法です。

26
jw013