Próbuję wyszukać podłańcuch „abc” w określonym pliku w linux / bash
Ja również:
grep '*abc*' myFile
Nic nie zwraca.
Ale jeśli to zrobię:
grep 'abc' myFile
Zwraca poprawnie dopasowania.
Teraz to nie jest dla mnie problem. Ale co, jeśli chcę grepować dla bardziej złożonego ciągu, powiedzmy
*abc * def *
Jak mógłbym to osiągnąć używając grep?
*
oznacza to samo w grep i egrep: jest to kwantyfikator oznaczający zero lub więcej poprzedzającego atomu. To zupełnie inna koncepcja niż symbole wieloznaczne używane przez powłokę.Odpowiedzi:
Gwiazdka to tylko operator powtórzenia , ale musisz powiedzieć, co powtarzasz.
/*abc*/
dopasowuje ciąg zawierający ab i zero lub więcej c (ponieważ druga * znajduje się na c; pierwsza jest bez znaczenia, ponieważ nie ma nic do powtórzenia). Jeśli chcesz coś dopasować, musisz powiedzieć.*
- kropka oznacza dowolny znak ( w określonych wytycznych ). Jeśli chcesz po prostu dopasować abc, możesz po prostu powiedziećgrep 'abc' myFile
. Aby uzyskać bardziej złożone dopasowanie, musisz użyć.*
-grep 'abc.*def' myFile
dopasuje ciąg zawierający abc, po którym następuje def, z czymś opcjonalnie pomiędzy.Aktualizacja na podstawie komentarza:
*
w wyrażeniu regularnym nie jest dokładnie tym samym, co * w konsoli. W konsoli * jest częścią konstrukcji glob i działa tylko jako symbol wieloznaczny (na przykładls *.log
wyświetla listę wszystkich plików kończących się na .log). Jednak w wyrażeniach regularnych * jest modyfikatorem, co oznacza, że ma zastosowanie tylko do poprzedzającego go znaku lub grupy. Jeśli chcesz, aby * w wyrażeniach regularnych działał jak symbol wieloznaczny, musisz użyć tego,.*
jak wspomniano wcześniej - kropka jest symbolem wieloznacznym, a gwiazdka podczas modyfikowania kropki oznacza znalezienie jednej lub więcej kropek; to znaczy. znajdź jedną lub więcej dowolnych postaci.źródło
*
oznacza „0 lub więcej”, a grep jest domyślnie chciwy. Należy zauważyć, że w grep podstawowych wyrażeniach regularnych metaznaki?
,+
,{
,|
,(
, i)
tracą swoje szczególne znaczenie. Więcej informacji:Znak kropki oznacza dopasowanie dowolnego znaku, więc
.*
oznacza zero lub więcej wystąpień dowolnego znaku. Prawdopodobnie masz na myśli.*
raczej używanie niż tylko*
.źródło
„Znak zodiaku” ma znaczenie tylko wtedy, gdy coś się przed nim znajduje. Jeśli nie ma narzędzia (w tym przypadku grep), może to potraktować jako błąd. Na przykład:
'*xyz' is meaningless 'a*xyz' means zero or more occurrences of 'a' followed by xyz
źródło
Użyj grep -P - co włącza obsługę wyrażeń regularnych w stylu Perla.
grep -P "abc.*def" myfile
źródło
Wyrażenie, które wypróbowałeś, podobnie jak te, które działają w wierszu poleceń powłoki na przykład w Linuksie, nazywa się „ glob ”. Wyrażenia glob nie są pełnymi wyrażeniami regularnymi , których używa grep do określania ciągów znaków, które mają być wyszukiwane. Oto (stary, mały) post o różnicach. Wyrażenia glob (jak w „ls *”) są interpretowane przez samą powłokę.
Możliwe jest tłumaczenie z globów na RE, ale zazwyczaj musisz to zrobić w głowie.
źródło
Nie używasz wyrażeń regularnych, więc Twój wybrany wariant grep powinien być taki
fgrep
, który będzie zachowywał się tak, jak tego oczekujesz.źródło
fgrep
jest obecnie przestarzała,grep -f
należy jej używać.Wypróbuj grep -E dla rozszerzonej obsługi wyrażeń regularnych
Spójrz także na:
Strona podręcznika grep
źródło
To może być odpowiedź, której szukasz:
Chodzi tylko o to, że ... wyświetli wiersze, w których "def" jest przed OR po "abc"
źródło
To zadziałało dla mnie:
grep ". * $ {wyrażenie}" - w cudzysłowach poprzedzonych kropką. Gdzie „wyrażenie” to dowolny ciąg, którego potrzebujesz na końcu linii.
Standardowy unix grep bez dodatkowych przełączników.
źródło
„*” działa jako modyfikator dla poprzedniego elementu. Zatem „abc * def” wyszukuje „ab”, po którym następuje 0 lub więcej „c”, a następnie „def”.
To, czego prawdopodobnie potrzebujesz, to „abc. * Def”, które wyszukuje „abc”, po którym następuje dowolna liczba znaków, a następnie „def”.
źródło