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