Chciałbym uzyskać dopasowanie wielu wzorców z niejawnym AND między wzorami, tj. Równoważne z uruchomieniem kilku greps w sekwencji:
grep pattern1 | grep pattern2 | ...
Jak więc przekonwertować to na coś takiego?
grep pattern1 & pattern2 & pattern3
Chciałbym użyć pojedynczego grepa, ponieważ dynamicznie buduję argumenty, więc wszystko musi mieścić się w jednym ciągu. Użycie filtru jest funkcją systemową, a nie grep, więc nie jest to argumentem.
Nie myl tego pytania z:
grep "pattern1\|pattern2\|..."
To jest dopasowanie wielu wzorców LUB .
grep
regular-expression
Greenoldman
źródło
źródło
Odpowiedzi:
agrep
można to zrobić za pomocą tej składni:Dzięki GNU
grep
, gdy jest zbudowany z obsługą PCRE, możesz:Z ast
grep
:(dodanie
.*
s jako<x>&<y>
dopasowuje ciągi, które pasują do obu<x>
i<y>
dokładnie ,a&b
nigdy nie będą pasować, ponieważ nie ma takiego ciągu, który może być jednocześniea
ib
jednocześnie)Jeśli wzorce się nie nakładają, możesz również wykonać następujące czynności:
Najlepszym przenośnym sposobem jest prawdopodobnie
awk
jak już wspomniano:Z
sed
:Uwaga: wszystkie będą miały różną składnię wyrażeń regularnych.
źródło
agrep
Składnia nie działa dla mnie ... która wersja została wprowadzona w?agrep
można znaleźć w glimpse / webglimpse . Być może masz inną implementację. Miałem błąd dla wersji AST-grep chociaż opcja dla wzmożone wyrażeniach regularnych jest-X
, nie-A
.agrep
wersję 0.8.0 na Fedorze 23. Wygląda to inaczejagrep
niż ta, do której się odwołujesz.agrep
.awk '/p1/ && /p2/ {n++}; END {print 0+n}'
Nie podałeś wersji grep, to ważne. Niektóre silniki wyrażeń regularnych umożliwiają wielokrotne dopasowanie pogrupowane według AND za pomocą „&”, ale jest to niestandardowa i nieprzenośna funkcja. Ale przynajmniej GNU grep tego nie obsługuje.
OTOH możesz po prostu zastąpić grep sed, awk, perl itp. (Wymienione w kolejności rosnącej masy). W przypadku awk polecenie wyglądałoby tak
i można go łatwo skonfigurować w wierszu poleceń.
źródło
awk
używa ERE, np. Odpowiednikagrep -E
, w przeciwieństwie do BRE, któregrep
używa zwykły .awk
Wyrazy regularne nazywane są ERE, ale w rzeczywistości są nieco idiosynkratyczne. Oto prawdopodobnie więcej szczegółów, niż ktokolwiek się troszczy: wiki.alpinelinux.org/wiki/Regexawk
- po prostu wiedząc, że im więcej, tym lepiej).{ print; }
część nie była tak naprawdę potrzebna ani przydatna.Jeśli
patterns
zawiera jeden wzór w wierszu, możesz zrobić coś takiego:Lub dopasowuje podciągi zamiast wyrażeń regularnych:
Aby wydrukować wszystkie zamiast bez linii na wejściu w przypadku, gdy
patterns
jest pusta, wymieńNR==FNR
sięFILENAME==ARGV[1]
lub zARGIND==1
wgawk
.Funkcje te drukują wiersze STDIN, które zawierają każdy ciąg znaków określony jako argument jako podłańcuch.
ga
oznacza grep all igai
ignoruje wielkość liter.źródło
To nie jest bardzo dobre rozwiązanie, ale ilustruje nieco fajną „sztuczkę”
źródło
chained-grep()
lubfunction chained-grep
ale niefunction chained-grep()
: unix.stackexchange.com/questions/73750/...git grep
Oto składnia przy użyciu
git grep
łączenia wielu wzorców przy użyciu wyrażeń logicznych :Powyższe polecenie wypisze linie pasujące do wszystkich wzorów jednocześnie.
Sprawdź
man git-grep
pomoc.Zobacz też:
Dla operacji LUB zobacz:
źródło
ripgrep
Oto przykład z użyciem
rg
:Jest to jedno z najszybszych narzędzi greppingowych, ponieważ zostało zbudowane na silniku regularnym Rust, który wykorzystuje skończone automaty, SIMD i agresywne optymalizacje dosłowne, aby wyszukiwanie było bardzo szybkie.
Zobacz także powiązane żądanie funkcji w GH-875 .
źródło
Oto moje zdanie, a to działa na słowa w wielu wierszach:
Użyj,
find . -type f
a następnie tyle-exec grep -q 'first_word' {} \;
i ostatnie słowo kluczowe z
-exec grep -l 'nth_word' {} \;
-q
-l
pliki pokazów cichych / cichych z dopasowaniemPoniższa lista zwraca nazwy plików zawierające słowa „królik” i „dziura”:
find . -type f -exec grep -q 'rabbit' {} \; -exec grep -l 'hole' {} \;
źródło
Aby znaleźć WSZYSTKIE słowa (lub wzory), możesz uruchomić grep w pętli FOR . Główną zaletą jest tutaj wyszukiwanie z listy wyrażeń regularnych .
EDYTUJ moją odpowiedź na prawdziwym przykładzie:
Teraz uruchommy go na tym pliku:
źródło
ALL
operatora, twój kod działa jakOR
operator, a nieAND
. I btw. do tego (OR
) jest o wiele łatwiejsze rozwiązanie podane bezpośrednio w pytaniu.AND
operatora, co oznacza, że plik jest tylko pozytywnym trafieniem, jeśli pasuje do wzoru A i wzoru B i wzoru C i ...AND
W twoim przypadku plik jest pozytywny, jeśli pasuje wzór A lub wzór B lub ... Czy widzisz teraz różnicę?AND
je. Następnie powinieneś przepisać skrypt, aby działał na wielu plikach - wtedy może zdajesz sobie sprawę, że odpowiedź na to pytanie jest już gotowa, a próba nie przynosi niczego do stołu, przepraszam.