コマンドラインから正規表現バックスラッシュをエスケープするために必要なバックスラッシュの数

コマンドラインから正規表現バックスラッシュをエスケープするために必要なバックスラッシュの数

最近、コマンドラインでいくつかの正規表現を使用するのに問題があり、バックスラッシュを一致させるために異なる数の文字を使用できることがわかりました。数値は、正規表現で使用される引用符(なし、一重引用符、二重引用符)によって異なります。何を意味するかについては、次のbashセッションを参照してください。

echo "#ab\\cd" > file
grep -E ab\cd file
grep -E ab\\cd file
grep -E ab\\\cd file
grep -E ab\\\\cd file
#ab\cd
grep -E ab\\\\\cd file
#ab\cd
grep -E ab\\\\\\cd file
#ab\cd
grep -E ab\\\\\\\cd file
#ab\cd
grep -E ab\\\\\\\\cd file
grep -E "ab\cd" file
grep -E "ab\\cd" file
grep -E "ab\\\cd" file
#ab\cd
grep -E "ab\\\\cd" file
#ab\cd
grep -E "ab\\\\\cd" file
#ab\cd
grep -E "ab\\\\\\cd" file
#ab\cd
grep -E "ab\\\\\\\cd" file
grep -E 'ab\cd' file
grep -E 'ab\\cd' file
#ab\cd
grep -E 'ab\\\cd' file
#ab\cd
grep -E 'ab\\\\cd' file

これは次のことを意味します。

  • 引用符なしで1つのバックスラッシュを4〜7個の実際のバックスラッシュと一致させることができます。
  • 二重引用符を使用すると、バックスラッシュを3〜6個の実際のバックスラッシュと一致させることができます。
  • 一重引用符を使用すると、バックスラッシュを2〜3個の実際のバックスラッシュと一致させることができます。

私が知る限り、シェルは追加のバックスラッシュを無視します(bashのマニュアルページにあります)。

「引用符のないバックスラッシュ(\)はエスケープ文字です。次の文字のリテラル値を保持します。」

一重引用符ではエスケープが行われないため、一重引用符の例では機能しません。

grep コマンドは余分なバックスラッシュを無視します ("\c" は単に "c" エスケープですが、"c" は正規表現で特別な意味がないので "c" と同じです)。

これは、一重引用符付きの例の動作を説明していますが、他の2つの例、特に引用符がない二重引用符文字列の間に違いがある理由をよく理解していません。

Bash のマニュアルページから再引用するには、次のようにします。

「文字を二重引用符で囲むと、履歴拡張が有効になっている場合は、$、`、\、!を除く引用符内のすべての文字のリテラル値が保持されます。」

私はGNU awk(例えば)を使って同じawk /ab\cd/{print} file結果を得ました。

ただし、Perlは他の結果を示しています(例:使用perl -ne "/ab\\cd/"\&\&print file)。

  • 引用符がない場合は、バックスラッシュを4〜5個の実際のバックスラッシュと一致させることができます。
  • 二重引用符を使用すると、バックスラッシュを3〜4個の実際のバックスラッシュと一致させることができます。
  • 一重引用符を使用すると、1つのバックスラッシュと2つの実際のバックスラッシュを一致させることができます。

grepコマンドとawkコマンドラインで引用符なしの正規表現文字列と二重引用符で囲まれた正規表現文字列の違いを説明できる人はいますか?私は通常Perlの1行を使用しないので、Perlの動作の説明にはあまり興味がありません。

ベストアンサー1

引用しない例では、各\\ペアは1つのバックスラッシュをgrepに渡すため、4つのバックスラッシュは2つのバックスラッシュをgrepに渡します。これは単一のバックスラッシュに変換されます。 6つのバックスラッシュは3をgrepに渡します。これは1つのバックスラッシュに変換され、1はと\c同じですc。バックスラッシュがもう1つあってもシェル\c->に変換されるので、何も変更されません。cシェルのバックスラッシュ8個はgrepの4個で、これは2個に変換されるため、もはや一致しません。

二重引用符で囲まれた例については、bashのマニュアルページの2番目の引用符の後に続くものを参照してください。

バックスラッシュは、$、`、"、\、または改行文字のいずれかが後に続く場合にのみ特別な意味を維持します。

つまり、奇数のバックスラッシュを指定するとシーケンスはで終わり、\cunquotedcと同じですが、引用されるとバックスラッシュは特別な意味を失い、\cgrepに渡されます。これが「可能な」バックスラッシュ(つまり、サンプルファイルと一致するパターンを構成するバックスラッシュ)の範囲が1つずつ減った理由です。

おすすめ記事