以下のコードを試して0(例:)の結果を取得しようとしました$? -eq 0
が、何らかの理由で常に失敗します。
echo "INBOUND_PATH|/tmp" | grep -E '^\(INBOUND_PATH\)\|\(.*\)$';
echo $?
逆参照を生成しようとする理由は、文字列形式が有効な場合は、次のようにディレクトリを切り取るためです。
g_inboundDir=grep -E 's/^\(INBOUND_PATH\)\|(.*)$/\2';
答え1
空白とすべての答えをまとめてman grep
grep()のマニュアルページを見ると、2つの主要な正規表現タイプ、つまり基本正規表現と拡張正規表現があります。
man grepによると:
基本正規表現と拡張正規表現基本正規
表現では、メタ文字?、+、{、|、(および)はバックスラッシュバージョン\?、+、{、\ |、(および)の代わりに特別な意味を失います。
つまり、エスケープされた括弧を使用するか、必要でない場合は、エスケープされた類似または単一の()
grepキャプチャグループを使用できます。grep \(....\)
grep -E
egrep
egrep '(....)'
sedにも同じルールが適用されます。単純なsedはデフォルトの正規表現を理解しているので、グループをキャプチャするにはエスケープが必要です。またはsed 's/\(....\)\(...\)/\2/'
、sedの実装に応じて、withまたはswitchで拡張正規表現サポートを有効にすることもできます。sed
-E
-r
sed -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の角かっこをグループキャプチャに使用するため、リテラル角かっこと一致するように角括弧をエスケープする必要があります。
答え2
文字列の基本的なチェックはそれほど複雑ではありません。
echo "INBOUND_PATH|/tmp" | grep -q '^INBOUND_PATH|.*$'
私は2番目がgrepではなくsedであることを意味すると仮定します。
g_inboundDir=$(echo "INBOUND_PATH|/tmp" | sed 's/^\(INBOUND_PATH\)|\(.*$\)/\2/')
-Eがないことに注意してください。欠落した末尾/も修正しました。
答え3
拡張正規表現 -E を追加したい。
-E、--extended-regexp PATTERNを拡張正規表現(ERE、以下を参照)として解釈します。
そしてまだそれから逃げています。不要。
$ echo "INBOUND_PATH|/tmp" | grep -E '^(INBOUND_PATH)\|(\/.*)'; echo $?
INBOUND_PATH|/tmp
0
一方、次のものを使用できます。エグレフ-Eなしで同じ効果を持ちます。