Pourquoi dois-je échapper deux fois à un «point»?

13

Je sais que l'on peut échapper à un caractère spécial comme *(){}$avec \afin d'être considéré comme des littéraux.
Par exemple \*ou\$

Mais dans le cas où .je dois le faire deux fois, comme \\.sinon, il est considéré comme un caractère spécial. Exemple:

man gcc | grep \\.

Pourquoi en est-il ainsi?

Utilisateur enregistré
la source
Pouvez-vous donner le cas où vous devez vous échapper deux fois?
cuonglm
man bash|grep \\.pourrait être un exemple.
Utilisateur enregistré le
3
Plus précisément, vous n'échappez pas au point deux fois, vous échappez au caractère d'échappement pour qu'il soit transmis à grep
Cthulhu
5
Vous pouvez utiliser des guillemets pour éviter l' échappement des caractères de barre oblique inverse: man gcc | grep '\.'.
Leonid Beschastny
1
Je préfère fortement la suggestion de @ LeonidBeschastny en raison de la clarté de ce qui se passe
Izkata

Réponses:

24

En règle générale, vous ne devez vous échapper qu'une seule fois pour que le caractère spécial soit considéré comme littéral. Parfois, vous devez le faire deux fois, car votre modèle est utilisé par plusieurs programmes.

Discutons de votre exemple:

man gcc | grep \\.

Cette commande est interprétée par deux programmes, bashinterprète et grep. La première cause de fuite bashsait \est littérale, donc la seconde passe grep.

Si vous échapper qu'une seule fois, \., bashsaura ce point est littérale, et de passer .à grep. Lorsque vous grepvoyez cela ., il pense que le point est un caractère spécial, pas littéral.

Si vous vous échappez deux fois, bashpassera le modèle \.à grep. grepSachez maintenant que c'est un point littéral.

cuonglm
la source
: Donc, le caractère d'échappement pour dot dépend-il du nombre de canaux que nous utilisons? .Par exemple cmd | cmd | cmd | cmd \\\\. Est-ce exact????
Thushi
6
@Thushi: Non. Cela n'a rien à voir avec le fait que vous utilisez un (ou plusieurs) caractère de pipe, mais s'applique même pour grep \\. my_file. La ligne de commande est interprétée par le shell, en utilisant le premier \ pour échapper au second, donc l'un \ est passé littéralement à grep. Le point .n'est pas spécial pour le shell, il est donc transmis textuellement de toute façon. Grep lit ensuite le (single) \ et l'utilise pour échapper au point ..
Ansgar Esztermann
@AnsgarEsztermann: Oui, c'est vrai, c'est vérifié, merci :)
Thushi
2
Je crois que la réponse est quelque peu incorrecte en ce qu'elle dit: "La première fuite provoque bash sait. Est littérale, la seconde est pour grep.". En fait, le premier échappement permet à bash de savoir que \ est létéral et de passer \. à grep.
Cthulhu
@Gnouc Je ne pense pas que ce soit le cas. echo .dans le bash juste ... fait écho au .caractère bach .
Cthulhu