Linux grepと正規表現の問題

Linux grepと正規表現の問題

以下のコードを試して0(例:)の結果を取得しようとしました$? -eq 0が、何らかの理由で常に失敗します。

echo "INBOUND_PATH|/tmp" | grep -E '^\(INBOUND_PATH\)\|\(.*\)$';

echo $?

逆参照を生成しようとする理由は、文字列形式が有効な場合は、次のようにディレクトリを切り取るためです。

g_inboundDir=grep -E 's/^\(INBOUND_PATH\)\|(.*)$/\2';

ベストアンサー1

空白とすべての答えをまとめてman grepgrep()のマニュアルページを見ると、2つの主要な正規表現タイプ、つまり基本正規表現と拡張正規表現があります。

man grepによると:

基本正規表現と拡張正規表現基本正規
表現では、メタ文字?、+、{、|、(および)はバックスラッシュバージョン\?、+、{、\ |、(および)の代わりに特別な意味を失います。

つまり、エスケープされた括弧を使用するか、必要でない場合は、エスケープされた類似または単一の()grepキャプチャグループを使用できます。grep \(....\)grep -Eegrepegrep '(....)'

sedにも同じルールが適用されます。単純なsedはデフォルトの正規表現を理解しているので、グループをキャプチャするにはエスケープが必要です。またはsed 's/\(....\)\(...\)/\2/'、sedの実装に応じて、withまたはswitchで拡張正規表現サポートを有効にすることもできます。sed-E-rsed -E 's/(...)(...)/\2/'

したがって、次のコマンドはすべて有効です。

$ echo "INBOUND_PATH|/tmp" | grep '^\(INBOUND_PATH\)|\(.*\)$';echo $?
INBOUND_PATH|/tmp
0

$ echo "INBOUND_PATH|/tmp" | egrep '(INBOUND_PATH)\|(.*)$';echo $?
INBOUND_PATH|/tmp
0

$ echo "INBOUND_PATH|/tmp" | sed 's/^\(INBOUND_PATH\)|\(.*$\)/\2/'
/tmp

$ echo "INBOUND_PATH|/tmp" | sed -E 's/(INBOUND_PATH)\|(.*)$/\2/'
/tmp

さまざまな正規表現で特殊記号を逆に処理する方法に注意してください。

|たとえば、上記のコマンドでパイプシンボルを処理するをご覧ください。
BRE(基本正規表現):
リテラルパイプシンボルと一致させるためにパイプシンボルをエスケープする必要はありません。
BREでエスケープされたパイプシンボルはOR演算子として扱われます(あなたの場合は予期せず動作します)。

同様に、BRE では、リテラル角かっこと一致させるためにエスケープ角かっこを使用する必要はありませんが、グループをキャプチャするにはエスケープ角( )かっこが必要です。

拡張正規表現(ERE):
文字通り一致するには、パイプ記号をエスケープする必要があります。デフォルトでは、EREはパイプシンボルがOR演算子として処理されるためです(BREと比較して処理が反対です)。

(同様に、EREはデフォルトでEREの角かっこをグループキャプチャに使用するため、リテラル角かっこと一致するように角括弧をエスケープする必要があります。

おすすめ記事