Używanie grep do wyszukiwania ciągu z kropką

196

Próbuję wyszukać ciąg 0.49(z kropką) za pomocą polecenia

grep -r "0.49" *

Ale to, co się dzieje jest to, że ja też dostaję niechciane rezultaty, które zawiera ciąg znaków, takich jak 0449, 0949etc ,. Rzecz w tym, że linux traktuje kropkę (.) Jako dowolny znak i przynosi wszystkie wyniki. Ale chcę uzyskać wynik tylko dla „0.49”.

Varun Kumar
źródło

Odpowiedzi:

238

grepużywa wyrażeń regularnych; .oznacza „dowolny znak” w wyrażeniu regularnym. Jeśli chcesz ciągiem znaków, należy użyć grep -F, fgreplub uciec .do\. .

Nie zapomnij zawinąć łańcucha w podwójne cudzysłowy. Albo powinieneś użyć\\.

Zatem twoim poleceniem będzie:

grep -r "0\.49" *

lub

grep -r 0\\.49 *

lub

grep -Fr 0.49 *
geekozaur
źródło
58
Musiałem uciec dwa razy, żeby \\.to zadziałało. Używam Zsh.
Nikos Renieris,
5
@NikosRenieris, czy zawijałeś ciąg greppingu podwójnymi cudzysłowami?
Justus Romijn
@JustusRomijn Myślę, że tak, tak.
Nikos Renieris,
15
będziesz musiał użyć go także \\.do uderzenia lub "\."ucieczki z powłoki.
Tomofumi,
36

grep -F -r '0.49' *traktuje 0,49 jako „stały” ciąg zamiast wyrażenia regularnego. To sprawia, że .traci swoje specjalne znaczenie.

Joni
źródło
22

Musisz uciec .jak "0\.49".

A .to metaznak wyrażenia regularnego pasujący do dowolnego znaku (oprócz nowej linii). Aby dopasować literalny okres, musisz go uciec.

kodaddict
źródło
6

Po prostu uciec .

grep -r "0\.49"

cppcoder
źródło
5

Możesz także użyć "[.]"

grep -r "0[.]49"
skan
źródło
5

Jest tu tak wiele odpowiedzi sugerujących ucieczkę od kropki, \.ale ciągle napotykałem ten problem: \.daje mi ten sam wynik co.

Jednak te dwa wyrażenia działają dla mnie:

$ grep -r 0\\.49 *

I:

$ grep -r 0[.]49 *

Używam „normalnej” powłoki bash na Ubuntu i Archlinux.

Edytuj lub, zgodnie z komentarzami:

$ grep -r '0\.49' *

Zauważ, że pojedyncze cytaty robią różnicę tutaj.

Afr
źródło
3
Musisz zacytować wyrażenie regularne z powłoki lub uciec z samego ukośnika odwrotnego, aby powłoka go nie wykorzystała. grep '\.'lub grep \\.. ).
tripleee
IMHO, jest to najczystsza poprawna odpowiedź, z komentarzem @tripleee jest najbardziej kompletna. użycie [] (które reprezentuje podzbiór znaków, do którego pasuje pojedynczy znak) to niezły hack.
jringoot
@jringoot Poważnie? Myślę, że to wcale nie jest jasne - bardziej przypomina pytanie uzupełniające od kogoś, kto nie znał cytowania.
tripleee
Jest jasne, ponieważ oba wyrażenia działają bezpośrednio, a nawet wiele innych zakłada cytowanie lub potrzebę podwójnej zmiany znaczenia, aby uniknąć wtórnej interpretacji powłoki jako trywialnej. Nie mogę już zmienić komentarza (limit 5 minut). Mój komentarz mógłby być lepszy: „w połączeniu z komentarzem @tripleee jest to najbardziej kompletna odpowiedź. Ponieważ oba polecenia działają natychmiast, a cytowanie jest kompletne”
jringoot
1
To, co zwykle polecam, to „zawsze używaj cudzysłowu w wyrażeniach regularnych”. Nie jest „kompletna”, ale wykonuje zadanie i oznacza, że ​​musisz zrozumieć cytowanie lub żyć według tej prostej zasady.
tripleee
4

Kropka ucieczki. Przykładowe polecenie będzie.

grep '0\.00'
tuxuday
źródło
4

Możesz uciec przed kropką i innymi znakami specjalnymi, używając \

na przykład. grep -r "0 \ .49"

Kevin Davis
źródło
Przypomnienie dla przyszłego czytelnika, \.otoczenie cytatami jest konieczne, aby działało.
Fruit
1

Możesz także wyszukiwać za pomocą opcji - opcja, która zasadniczo ignoruje wszystkie znaki specjalne i nie zostanie zinterpretowana przez grep.

$ cat foo |grep -- "0\.49"
smc
źródło