Po pierwsze, zwróć uwagę, że pojedynczy ukośnik pasuje zbyt wiele:
$ echo $'eegg \n e.g.' | grep e\.g\.
eegg
e.g.
Jeśli chodzi o Basha , okres ucieczki jest taki sam jak okres. Bash przechodzi na okres grep . Dla grep kropka pasuje do wszystkiego.
Teraz rozważ:
$ echo $'eegg \n e.g.' | grep e\\.g\\.
e.g.
$ echo $'eegg \n e.g.' | grep e\\\.g\\\.
e.g.
$ echo $'eegg \n e.g.' | grep e\\\\.g\\\\.
$
Gdy Bash widzi podwójny ukośnik, redukuje go do pojedynczego ukośnika i przekazuje go na grep, który w pierwszym z trzech powyższych testów widzi, jak chcemy, pojedynczy ukośnik przed kropką. Tak więc robi to właściwą rzecz.
Dzięki potrójnemu ukośnikowi Bash redukuje pierwsze dwa do jednego ukośnika. Potem widzi \.. Ponieważ okres ucieczki nie ma specjalnego znaczenia dla Bash, jest on redukowany do zwykłego okresu. W rezultacie grep widzi, jak chcemy, cięcie przed kropką.
Z czterema ukośnikami Bash redukuje każdą parę do jednego ukośnika. Bash przechodzi na grep dwa ukośniki i kropkę. grep widzi dwa ukośniki i kropkę i redukuje dwa ukośniki do jednego dosłownego ukośnika. O ile na wejściu nie ma dosłownego ukośnika, po którym następuje dowolny znak, nie ma żadnych dopasowań.
Aby zilustrować to ostatnie, pamiętaj, że w pojedynczych cudzysłowach wszystkie znaki są dosłowne. Tak więc, biorąc pod uwagę następujące trzy wiersze wejściowe, polecenie grep pasuje tylko do wiersza z literalnym ukośnikiem na wejściu:
$ echo 'eegg
e.g.
e\.g\.' | grep e\\\\.g\\\\.
e\.g\.
Podsumowanie zachowania Basha
W przypadku Bash obowiązują następujące zasady
Dwa ukośniki są zredukowane do jednego ukośnika.
Cięcie przed normalnym znakiem, takim jak kropka, jest po prostu normalnym znakiem (kropka).
A zatem:
$ echo \. \\. \\\. \\\\.
. \. \. \\.
Istnieje prosty sposób na uniknięcie tego zamieszania: w wierszu poleceń Bash wyrażenia regularne należy umieszczać w cudzysłowach. Wewnątrz pojedynczych cytatów Bash pozostawia wszystko w spokoju.
$ echo '\. \\. \\\. \\\\.' # Note single-quotes
\. \\. \\\. \\\\.
\\\.i da grep,\.ale tak nie jest. dobre pytanie