Próbuję użyć, grep
aby dopasować wiersze zawierające dwa różne ciągi. Próbowałem następujących, ale to pasuje do wierszy zawierających ciąg1 lub ciąg2, które nie są tym, czego chcę.
grep 'string1\|string2' filename
Jak więc dopasować grep
tylko linie zawierające oba ciągi ?
Odpowiedzi:
Możesz użyć
grep 'string1' filename | grep 'string2'
Lub,
grep 'string1.*string2\|string2.*string1' filename
źródło
grep -e "string1" -e "string2"
Myślę, że tego właśnie szukałeś:
Myślę, że takie odpowiedzi:
pasują tylko do przypadku, gdy oba są obecne, a nie jedno lub drugie lub oba.
źródło
grep -e "string1" -e "string2" filename
zrobiłby tego samego?How do I match lines that contains *both* strings?
Aby wyszukać pliki zawierające wszystkie słowa w dowolnej kolejności w dowolnym miejscu:
Pierwszy grep uruchamia wyszukiwanie rekurencyjne (
r
), ignorująci
wielkość liter ( ) i wyświetlając (drukując) nazwy plików pasujących (l
) dla jednego terminu ('action'
z pojedynczymi cudzysłowami) występujących w dowolnym miejscu pliku.Kolejne greps szukają innych terminów, zachowując rozróżnianie wielkości liter i wypisując pasujące pliki.
Ostateczna lista plików, które otrzymasz, będzie zawierać te warunki, w dowolnej kolejności w dowolnym miejscu pliku.
źródło
grep -ril 'foo' | xargs -d '\n' grep -il 'bar'
Jeśli masz
grep
z-P
opcją ograniczonegoperl
regex, można użyćktóry ma tę zaletę, że pracuje z nakładającymi się łańcuchami. Jest to nieco prostsze przy użyciu
perl
asgrep
, ponieważ możesz określić i logikę bardziej bezpośrednio:źródło
Twoja metoda była prawie dobra, brakuje tylko -w
źródło
grep -V
.grep -w 'regexp1\|regexp2' filename
|
Operator w wyrażeniu regularnym oznacza albo. To znaczy, że albo string1 albo string2 będą pasować. Mógłbyś:który potokuje wyniki pierwszego polecenia do drugiego grep. To powinno dać ci tylko linie, które pasują do obu.
źródło
Możesz spróbować czegoś takiego:
źródło
I jak ludzie sugerowali perl i python oraz zawiłe skrypty powłoki, tutaj proste podejście awk :
Po przejrzeniu komentarzy do zaakceptowanej odpowiedzi: nie, to nie robi wielu linii; ale nie o to też pytał autor pytania.
źródło
Nie próbuj do tego używać grep, zamiast tego użyj awk. Aby dopasować 2 wyrażenia regularne R1 i R2 w grep, można by pomyśleć, że będzie to:
w awk będzie to:
ale co jeśli
R2
nakłada się na podzbiór lub jest jego podzbioremR1
? To polecenie grep po prostu nie zadziałałoby, podczas gdy polecenie awk. Powiedzmy, że chcesz znaleźć wiersze zawierającethe
iheat
:Musisz do tego użyć 2 grepsa i fajki:
i oczywiście, jeśli rzeczywiście wymagałeś ich oddzielności, zawsze możesz napisać w awk ten sam wyrażenie regularne, którego używałeś w grep, i istnieją alternatywne rozwiązania awk, które nie wymagają powtarzania wyrażeń regularnych w każdej możliwej sekwencji.
Odkładając to na bok, co jeśli chcesz rozszerzyć swoje rozwiązanie, aby pasowało do 3 wyrażeń regularnych R1, R2 i R3. W grep byłby to jeden z tych złych wyborów:
podczas gdy w awk byłoby zwięzłe, oczywiste, proste, wydajne:
A jeśli teraz chcesz dopasować dosłowne ciągi znaków S1 i S2 zamiast wyrażeń regularnych R1 i R2? Po prostu nie możesz tego zrobić w jednym wywołaniu grep, musisz albo napisać kod, aby uciec od wszystkich metazarów RE przed wywołaniem grep:
lub ponownie użyj 2 greps i fajki:
które znowu są złymi wyborami, podczas gdy w awk po prostu używasz operatora łańcuchowego zamiast operatora wyrażenia regularnego:
Co teraz, jeśli chcesz dopasować 2 wyrażenia regularne w akapicie zamiast w wierszu? Nie można tego zrobić w grep, trywialny w awk:
Co powiesz na cały plik? Znowu nie można tego zrobić w grep i trywialnym w awk (tym razem używam GNU awk dla wieloznakowego RS dla zwięzłości, ale nie jest to dużo więcej kodu w żadnym awk lub możesz wybrać znak kontrolny, o którym wiesz, że nie będzie być na wejściu, aby RS zrobił to samo):
Więc - jeśli chcesz znaleźć wiele wyrażeń regularnych lub ciągów w linii, akapicie lub pliku, nie używaj grep, użyj awk.
źródło
awk '/R1/ && /R2/'
wielkość liter nie rozróżnia?awk -v IGNORECASE=1 '/R1/ && /R2/'
i przy każdym awkawk '{x=toupper($0)} x~/R1/ && x~/R2/'
GNU grep wersja 3.1
źródło
Znaleziono linie, które zaczynają się tylko 6 spacjami i kończą:
źródło
Powiedzmy, że musimy znaleźć liczbę wielu słów w pliku testowym pliku. Można to zrobić na dwa sposoby
1) Użyj polecenia grep z wzorcem dopasowania wyrażenia regularnego
2) Użyj polecenia egrep
Dzięki egrep nie musisz się martwić o wyrażenie i po prostu oddzielić słowa separatorem potokowym.
źródło
git grep
Oto składnia przy użyciu
git grep
wielu wzorców:Można również łączyć wzory z logicznych wyrażeń takich jak
--and
,--or
i--not
.Sprawdź
man git-grep
pomoc.Inne parametry do rozważenia:
Aby zmienić typ wzoru, można również użyć
-G
/--basic-regexp
(domyślnie),-F
/--fixed-strings
,-E
/--extended-regexp
,-P
/--perl-regexp
,-f file
i inne.Związane z:
Dla operacji LUB zobacz:
źródło
Umieść ciągi, które chcesz grepować w pliku
Następnie wyszukaj za pomocą -f
źródło
otrzyma wiersz ze string1 i string2 w dowolnej kolejności
źródło
Działa to w przypadku dokładnego dopasowywania słów i dopasowywania wyrazów bez rozróżniania wielkości liter, ponieważ używa się -i
źródło
dla dopasowania wieloliniowego:
lub
musimy tylko usunąć znak nowej linii i to działa!
źródło
Powinieneś mieć
grep
takie:źródło
Często napotykam ten sam problem, co twój i właśnie napisałem fragment skryptu:
Stosowanie:
Możesz umieścić go w .bashrc, jeśli chcesz.
źródło
Kiedy oba ciągi są w sekwencji, wstaw wzór pomiędzy
grep
komendą:Przykład, jeśli w pliku o nazwie znajdują się następujące wiersze
Dockerfile
:Aby uzyskać wiersz zawierający ciągi:
FROM python
aas build-python
następnie użyj:Następnie wynik wyświetli tylko wiersz zawierający oba ciągi :
źródło
ripgrep
Oto przykład z użyciem
rg
:Jest to jedno z najszybszych narzędzi grepowania, ponieważ zostało zbudowane na silniku regularnym Rdza który wykorzystuje skończone automaty, SIMD i agresywne optymalizacje dosłowne, aby wyszukiwanie było bardzo szybkie.
Użyj go, zwłaszcza gdy pracujesz z dużymi danymi.
Zobacz także powiązane żądanie funkcji w GH-875 .
źródło
string2
pojawia się wcześniejstring1
. Najprostszym rozwiązaniem tego problemu jestrg string1 file.txt | rg string2
.