Negatywne dopasowanie wielu wzorców Grep


14

Mam więc kilka dzienników Apache przy użyciu standardowego formatu dziennika. Chcę uzyskać wszystkie wiersze dziennika, które nie pochodzą z przeszukiwacza sieci.

Powiedzmy, że mam plik robot_patterns z wpisami takimi jak

Googlebot
msnbot-media
YandexBot
bingbot

Jeśli uruchomię polecenie grep -f robot_patterns *.log, otrzymam wszystkie wpisy od botów pasujących do powyższych wzorów. Moja aktualna lista zawiera ~ 30 wpisów botów i agentów, które chcę zignorować.

Ale chcę znaleźć wszystkie wpisy, które NIE pochodzą od botów . Dlatego próbuję grep -v -f robot_patterns *.logi grep nie zwraca żadnych wyników. Nie tego oczekuję ani nie pragnę i nie znajduję oczywistego sposobu na uzyskanie tego, czego chcę. Podczas korzystania z -vopcji połączonej z wieloma wzorami w pliku grep zwróci pasującą linię tylko wtedy, gdy pasuje do KAŻDEGO wzorca.


Kiedy wypróbowałem to w moim systemie, grep -v -f miał pożądane zachowanie, zwracając tylko linie, które nie pasowały do ​​żadnego z wzorców. Tak było w przypadku (GNU grep) 2.14.56-1e3d. Jakiego grepa używasz?
wingedsubmariner

Biegnę GNU grep 2.6.3.
Zoredache,

4
Zrobiłem trochę więcej testów i okazało się, że jeśli w pliku wzorców jest pusta linia, będzie pasować do każdej linii, powodując, że żadne linie nie będą zwracane przez -v. Nie jest to jednak problem z opcją -F, a -F może przyspieszyć grep dla twojego zadania - być może warto spróbować dla ciebie.
wingedsubmariner

Końcowa pusta linia! Argh ... To wydaje się być problemem. Jeśli chcesz, powinieneś dodać to jako odpowiedź.
Zoredache,

Odpowiedzi:


8

Jeśli w pliku wzorców znajduje się pusta linia, będzie pasować do każdej linii, co spowoduje, że nie zostaną zwrócone żadne linie -v. Jest tak, ponieważ wiersze są interpretowane jako wyrażenia regularne, a puste wyrażenie regularne zawsze będzie pasować.

Nie stanowi to jednak problemu -F, ponieważ grepignoruje puste linie za pomocą -F.
-Fpowoduje grepinterpretację wierszy jako prostych ciągów do wyszukiwania i może przyspieszyć, grepjeśli nie są potrzebne wyrażenia regularne.


1
GNU fgrepignorowanie tego pustego ciągu było błędem, który został naprawiony w 2.19 ( commit 2d3832e1ff772dc1a374bfad5dcc1338350cc48b , więc nie powinieneś na nim polegać
Stéphane Chazelas,

13

Możesz spróbować:

grep -vE 'Googlebot|msnbot-media|YandexBot|bingbot' yourlogfile

2
Witamy w systemach Unix i Linux. OP ma listę około 30 ciągów, które chce zignorować, a cztery, które przedstawił jako przykłady, mają średnią długość dziesięciu znaków, więc twoje polecenie może mieć ponad 300 znaków. Jest to prawdopodobnie trudne do utrzymania (a nawet do odczytania). Czy możesz zmodyfikować swoją odpowiedź, aby kierowała nią lista ciągów OP? …………………………………………………… PS Czy zauważyłeś, że odpowiedź została znaleziona? - PO nauczył się, jak zdobyć oryginalne podejście do pracy.
G-Man mówi „Przywróć Monikę”

2
Dlaczego negatywnie oceniam moją odpowiedź? : /
Orsius

3
Świetna odpowiedź. Ma wyrażenie regularne OR i opcja -vE była pomocna.
Kirt Carson

3
To jest odpowiedź na pytanie, które większość ludzi prawdopodobnie próbuje rozwiązać.
Perfi
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.