Alternatywy dla 'egrep -o “success | error | fail | <nazwa_pliku> | sortuj | uniq -c '

8

Czasami muszę sprawdzić niektóre dzienniki i robię to za pomocą tego polecenia:

egrep -o "success|error|fail" <filename> | sort | uniq -c

Przykładowe dane wejściowe:

test error on line 10
test connect success
test insert success
test started at 00:00
test delete  fail

Przykładowe dane wyjściowe:

1 error
1 fail
2 success

Chciałbym wiedzieć, czy ktoś wie, jak to zrobić za pomocą krótszego polecenia?

Zanim zapytasz, dlaczego chciałbym to zrobić innym poleceniem ... Nie ma specjalnego powodu, jestem po prostu ciekawy :)

Wolfy
źródło

Odpowiedzi:

4

Oto awksposób na zrobienie tego

awk 'BEGIN{RS=" "}/success/{s++}/fail/{f++}/error/{e++}END{print "Success:"s" Failed:"f" Error:"e}' abc

Ale te wszystkie wkładki będą nieco dłuższe niż nasze stare dobre grep

devav2
źródło
4

Nie, myślę, że jesteś tak dobry, jak to tylko możliwe. Oczywiście możesz to zrobić za pomocą jednego skryptu perla,

perl -nle  's/.*(error|fail|success).*/$1/ && $a{$_}++ ; END {  print "$_ $a{$_}" for keys %a } ' test.txt

... ale jest bardziej złożony i mniej intuicyjny.

styczeń
źródło
Do mojego pytania dodałem przykładowy wkład ... Mam nadzieję, że teraz jest bardziej jasne, co robi polecenie ... sory za niedogodności
Wolfy
1
OK, odpowiednio zmodyfikowałem perl oneliner. Nadal uważam, że twoje rozwiązanie z egrep jest lepsze i bardziej intuicyjne.
grudnia
2

Niewiele krótszy, ale ponieważ tak naprawdę nie potrzebujesz wyrażenia regularnego, jest fgrep( grep -F).

fgrep 'success
error
fail' "$filename" | sort | uniq -c

inny sposób na napisanie tego samego w bash:

fgrep $'success\nerror\nfail' "$filename" | sort | uniq -c
kojiro
źródło
1

Możesz napisać prosty skrypt bash, a następnie wywołać skrypt, na przykład:

#!/bin/bash
egrep -o "success|error|fail" "$1" | sort | uniq -c

i zapisz jako (na przykład) myscript.sh. Następnie zrób a chmod +x myscript.shi możesz to tak nazwać myscript.sh <filename>.

jeremija
źródło
Ale w tym przypadku polecenie jest takie samo ... właśnie utworzyłeś skrypt, który wywołuje polecenie ...
Wolfy
Myślałem, że chcesz tylko przyspieszyć grepowanie twoich logów. Ciekawe, dlaczego chcesz alternatywne polecenie, jeśli to, które już dostarczyłeś, robi dla ciebie dobrą robotę?
jeremija
tak jak powiedziałem: jestem po prostu ciekawy, jak inni robią coś takiego ... wiele razy zdałem sobie sprawę, że ludzie znają jakiś fantazyjny / miły sposób na robienie rzeczy i uwielbiam uczyć się teraz sposobów na robienie rzeczy ...
Wolfy
2
W takim przypadku jesteś tą osobą :-) Twoja linia poleceń jest ładna, zwięzła, przejrzysta i wykorzystuje moc linii poleceń Uniksa. Czego jeszcze chcieć?
grudnia
0

Twoje polecenie, choć krótkie i słodkie, jest raczej okrężnym sposobem liczenia wystąpień danego terminu. Prawdopodobnie wybrałbym tępe, bezpośrednie podejście i użyłem flagi grep -c (która robi dokładnie to) wewnątrz pętli powłoki:

for i in success test fail; do echo `grep -c $i <filename>` $i; done

Nie tak krótki, nie tak ekscytujący, potencjalnie szybszy dla dużych plików dziennika (nie sort). Powiedziałbym, że to pranie.

Potrójny
źródło
-1

To może być fałszywa odpowiedź, ale myślę, że w tym przypadku sortjest całkiem bezużyteczna; może możesz to pominąć. Niemniej jednak tutaj używamy trzech różnych poleceń dla trzech różnych działań.

Możemy to skrócić, jeśli niektóre z nich zostaną osiągnięte z opcją grep, ale nie widzę, która ... :)

Alessio Tomelleri
źródło
2
Nie, nie jest, w przeciwnym razie uniq będzie liczyć tylko kolejne wystąpienia wyszukiwanych haseł. Np. Jeśli odniesiesz sukces, sukces, porażkę, sukces, to wynik Uniq będzie 2 success 1 fail 1 success.
grudnia
w porządku ... sry
Alessio Tomelleri,