2010-06-09 33 views
16

Grep działa inaczej, w zależności od tego, z jakim cytatem otaczam wyrażenie regularne. Nie potrafię zrozumieć, dlaczego tak jest. Oto przykład problemu:Cytaty podczas korzystania z grep?

hamiltont$ grep -e show\( test.txt 
    variable.show(); 
    variable.show(a); 
    variable.show(abc, 132); 
    variableshow(); 
hamiltont$ grep -e "show\(" test.txt 
grep: Unmatched (or \(
hamiltont$ grep -e 'show\(' test.txt 
grep: Unmatched (or \(

jestem po prostu zakładając, że istnieje jakiś właściwy sposób ująć regex z pojedynczym/podwójnym cudzysłowie. Jakaś pomoc?

FWIW, grep --version powraca grep (GNU grep) 2.5.1

Odpowiedz

23

Wiersz poleceń zawierający argumenty jest przetwarzany przez powłokę przed jej wykonaniem. Możesz użyć echo żeby zobaczyć, co robi powłoka:

$ echo grep -e show\( test.txt 
grep -e show(test.txt 

$ echo grep -e "show\(" test.txt 
grep -e show\(test.txt 

$ echo grep -e 'show\(' test.txt 
grep -e show\(test.txt 

Więc bez cudzysłowów odwrotny ukośnik dostaje usunięte czyniąc „(” normalny znaków dla grep (grep używa podstawowy regex domyślnie używać -E, aby korzystanie grep rozszerzony regex).

+0

Rozumiem, dzięki! – Hamy

+0

Nadal nie dostaję różnicy między pojedynczym a podwójnym cudzysłowem. W zamieszczonym przez Ciebie przykładzie wydają się robić to samo. –

+0

Co zrobić, jeśli mam wyrażeń regularnych grep, które powinny pasować do pojedynczego cudzysłowu lub podwójnego cudzysłowu, jak mogę go napisać grepem? 'grep '["] \' "' nie wydaje się działać ... – tonix

0

Nie wierzę, że to grep zachowuje się inaczej, to jest powłoka. Zakładam, że używasz bash

http://www.faqs.org/docs/bashman/bashref_8.html

Zasadniczo wersje podawane zachowują się inaczej na slash, w zależności od mechanizmu cytowania.

Oba cytowane przykłady działałyby bez slasha. W przypadku pierwszego, powłoka ucieknie (i przejdzie w pokazie (do grep dla wzorca)

2

Cytaty zmieniają to, co grep widzi. Odwrotny ukośnik (\) w nieokreślonym formularzu jest przetwarzany przez powłokę, która traktuje znaki po odwrotnym ukośniku jako specjalne. Dzieje się tak, zanim grep otrzyma parametr. grep widzi show (. Gdy używane są cudzysłowy (pojedyncze lub podwójne), powłoka interpretuje je jako "pozostaw zawartość w spokoju", tak więc grep widzi znaki \ (i \ () w grep i ona szuka nawiasem zamykającym - \)

BTW. Pojedyncze i podwójne obsługa cytat różni się w jaki sposób powłoka obsługuje zmienne powłoki, ale nie istnieją żadne zmienne powłoki w przykładzie

+0

Mam to, dzięki! – Hamy

3

w kolejności:

.
grep -e show(test.txt 

nie działa, ponieważ powłoka interpretuje ( jako specjalny, nawias, a nie tylko znak, i nie może znaleźć zamknięcia ).

Są zarówno praca:

grep -e 'show(' test.txt 
grep -e "show(" test.txt 

ponieważ powłoka traktuje cytowany tekst jak tylko tekst, i przekazuje go do grep.

te nie działają:

grep -e 'show\(' test.txt 
grep -e "show\(" test.txt 

ponieważ powłoka przechodzi show\( grep, grep widzi \( jako specjalny, nawias, a nie tylko charakter, i nie może znaleźć zamykanie \).

Powiązane problemy