「ドット」を2回エスケープする必要があるのはなぜですか?


13

リテラルと見なされるように*(){}$、withの\ような特殊文字をエスケープできることを知っています。
たとえば、\*または\$

しかし、.私はそれを2回し\\.なければならない場合、そうでなければそれは特別なキャラクターと見なされます。例:

man gcc | grep \\.

なぜそうなのですか?


あなたは二度逃げなければならないケースを与えることができますか?
cuonglm

man bash|grep \\.例かもしれません。
登録ユーザー14

3
より正確には、ドットを2回エスケープせず、エスケープ文字をエスケープして、grepに渡されるようにします
クトゥルフ14

5
引用符を使用して、バックスラッシュ文字のエスケープを回避できますman gcc | grep '\.'
レオニードベシャストニー14

1
@LeonidBeschastnyの提案を強くお勧めします。何が起こっているかがどれだけ明確かという理由からです。
Izkata 14

回答:


24

一般的に、特殊文字をリテラルと見なすために1回だけエスケープする必要があります。パターンは複数のプログラムで使用されるため、2回実行する必要があります。

あなたの例を議論しましょう:

man gcc | grep \\.

このコマンドは、bashインタープリターとの2つのプログラムによって解釈されgrepます。最初のエスケープ原因はリテラルであるbashこと\がわかっているため、2番目はのパスですgrep

あなたは一度だけをエスケープした場合、\.bashこのドットがリテラルである知っている、と渡します.grep。これをgrep見る.と、ドットはリテラルではなく特殊文字であると考えられます.

2回エスケープbashすると、パターン\.をに渡しますgrep。これgrepが文字通りのドットであることを知ってください。


:だから、ドットのエスケープ文字は使用するパイプの数に依存しますか?cmd | cmd | cmd \\\\。あれは正しいですか????
かくし14

6
@Thushi:いいえ。これは(または複数の)パイプ文字を使用しているという事実とは関係ありませんが、にも適用されgrep \\. my_fileます。コマンドラインはシェルによって解釈され、最初のコマンドラインを使用し\ て2番目のコマンドラインがエスケープされるため、1つ\ は文字通りgrepに渡されます。ドット.はシェルにとって特別なものではないので、とにかくそのまま渡されます。次に、Grepは(単一の)\ を読み取り、それを使用してdotをエスケープし.ます。
アンスガーエステルマン14

@AnsgarEsztermann:はい、それは本当です。それをチェックしました。ありがとう:)
テルシー14

2
私は答えが「bashが知っている最初のエスケープ原因は。がリテラルであり、2番目はgrepのためである」と言う点で多少間違っていると思います。実際、最初のエスケープはbashに\がleteralであることを知らせ、\を渡します。grepに。
クトゥルフ14

@Gnouc持ってないと思う。echo .バッシュでは...バッハの.キャラクターをエコーします。
クトゥルフ14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.