grepに二重バックスラッシュが必要なのはなぜですか?

grepに二重バックスラッシュが必要なのはなぜですか?

特殊文字が特別な動作を生成することを知っています。

$ echo 'abc[abc' | grep -o '['
grep: Invalid regular expression

一重引用符は、シェルの解釈やソース文字列の変更に関する問題を防ぎます。

また、これらの特殊文字の特別な解釈を避けるためにバックスラッシュが必要であることも知っています。

$ echo abc[abc | grep -o '\['
[

バックスラッシュ-specialChar(\[)を一致させるには、grepにさらにバックスラッシュが必要です。

$ echo 'abc\[abc' | grep -o '\\\['
\[

しかし、anのような単純な文字は特別ではなく、faと一致する\f必要はありません。追加脱出する:

$ echo 'abc\fabc' | grep -o '\f'
f

しかしそれははい:

$ echo 'abc\fabc' | grep -o '\\f'
\f

言葉次の文字列:

$ echo 'abc\fabc' | grep -F -o '\f'
\f

行って\fgrepが何とか説明することを証明してください。

これ手動状態:

'\'文字は、後に特定の一般文字が続くときに特別な意味を持ちます。
/s は
'[[:space:]]' と同義語である空白と一致します。

certain ordinary characters他の人もいるという暗示普通の人リストにはありません。特別な状態。

したがって、私の理解は、a \f(単一の文字のみを選択)がソース文字列と一致する必要があることです\f

私は何を見逃していますか?

関連:

1-grep: 末尾のバックスラッシュ

2-grepのエスケープスラッシュ「\」

サム -sedに一般的なバックスラッシュを表すために3つのバックスラッシュが必要なのはなぜですか?

答え1

ただし、fのような単純な文字は特別ではなく、\ fと一致させるために追加のエスケープは必要ありません。

$ echo 'abc\fabc' | grep -o '\f'
f

f特別ではありませんが、バックスラッシュは正規表現で特別です。一般文字の前にあるバックスラッシュの動作は、バックスラッシュエスケープを実装するユーティリティによって異なりますが、次のようになります。POSIX正規表現の場合、定義は次のとおりです。:

エスケープされていない文字 ( '\' ) が前にある一般文字の解釈は次のとおりです。はっきりしない、次の場合を除く:[ (){}、括弧内の式の1つ1]9

同様に、拡張正規表現では次のようになります。

一般文字は、ERE 特殊文字にリストされている ERE 特殊文字を除いて、サポートされる文字セットのすべての文字です。エスケープされていない()の前にある一般文字の解釈は、\\角括弧式のコンテキストを除いて定義されていません(ERE角括弧式を参照)。

grep(またはこれが使用する正規表現の実装)は単に\fwithとして解釈されるように選択しますf。バックスラッシュがf(特殊属性がなくても)の特殊属性を削除すると考えることもできます。バックスラッシュはEREでも同じように機能します。または任意の決定で。


これLinuxのマニュアルページregex(7)明示的な説明:

アトムは、[何よりも]a\の後に他の文字(!)が続きます(対応する文字が存在しないかのように、通常の文字と一致します\(!))。

私のMacでは、Cスタイルのエスケープ文字と同様にフォームフィード文字をgrep表しています。\fしたがってprintf '\f' | grep '\f'、一致すると、両方がページフィードとして解釈されます(printfこれを実行するように定義されています)。

答え2

私は何を見逃していますか?

grep文字列に関する限り、fこれは正規表現の一般的な文字なので、'\f'次のようになります'f'

$ echo 'abc\fabc' 
abc\fabc
$ echo 'abc\fabc' | grep -o '\f'
f
$ echo 'abc\fabc' | grep -o 'f'
f

しかし、fのような単純な文字は特別ではなく、エスケープする必要はありません。

$ echo 'abc\fabc' | grep -o '\f'

f

しかしそれははい:

$ echo 'abc\fabc' | grep -o '\\f'

\f

いいえ、そうではありません。前の例を振り返ると、次のようになります。

$ echo 'abc\fabc' | grep -o 'f'
f

マニュアルページre_format(7)レコードregexpは\fregexpと同じですf

... '\'の後に他の文字が続きます('\'が存在しないかのように通常の文字として扱われる文字と一致します)...

関連情報