2008-09-24 23 views
9

Mam dziennik dostępu do serwera, z sygnaturami czasowymi każdego żądania http, chciałbym uzyskać liczbę żądań w każdej sekundzie. Korzystanie sed i cut -c, dotychczas udało mi się wyciąć plik do zaledwie sygnatury czasowe, takie jak:Liczba wystąpień tokena w pliku

22-Sep-2008 20:00:21 +0000
22-wrz-2008 20:00:22 +0000
22-Sep-2008 20:00:22 +0000
22-Sep-2008 20:00:22 +0000
22-Sep-2008 20:00:24 +0000
22-wrz-2008 20:00:24 +0000

Co chciałbym dostać to n umber razy każdy unikalny znacznik czasu pojawia się w pliku. Na przykład, w powyższym przykładzie, chciałbym, aby uzyskać wyjście, które wygląda następująco:

22-Sep-2008 20:00:21 +0000: 1
22-wrz-2008 20:00: 22 +0000: 3
22-Sep-2008 20:00:24 +0000: 2

Użyłem sort -u filtrować listę znaczników czasu w dół do listy unikatowych tokenów, mając nadzieję, że mogę użyj grep jak

grep -c -f <file containing patterns> <file> 

, ale to tworzy pojedynczą linię wielkiej sumy pasujących linii.

Wiem, że można to zrobić w jednej linii, łącząc kilka narzędzi razem ... ale nie mogę o tym myśleć. Ktoś wie?

Odpowiedz

32

myślę szukasz

uniq --count 

-c, --count linie przedrostka według liczby wystąpień

+5

Należy pamiętać, że w przypadku innych zestawów danych konieczne może być posortowanie (1) przed uniq (1), ponieważ uniq będzie tylko grupować adj wyraźne duplikaty. –

+0

Tak, ale OP już powiedział, że sortuje rzeczy, więc zakładałem, że jest na szczycie tego rodzaju rzeczy ... –

+0

Musiałem użyć 'uniq -c' na OS X,' --count' dał mi błąd. –

-2

może użyć xargs? Nie mogę umieścić wszystkiego razem w mojej głowie tutaj, ale używaj xargs na twoim sortowaniu -u, tak aby dla każdego unikalnego sekundy można było grep oryginalnego pliku i zrobić wc -l aby uzyskać numer.

1

Używanie AWK z tablicami asocjacyjnymi może być kolejnym rozwiązaniem tego typu.

1

Tylko w przypadku, gdy chcesz wyjście w formacie pierwotnie określony (z liczbą wystąpień na końcu):

uniq -c logfile | sed 's/\([0-9]+\)\(.*\)/\2: \1/' 
0

Korzystanie awk:

cat file.txt | awk '{count[$1 " " $2]++;} \ 
        END {for(w in count){print w ": " count[w]};}' 
0

rozwiązanie Toma:

awk '{count[$1 " " $2]++;} END {for(w in count){print w ": " count[w]};}' file.txt 

działa bardziej ogólnie.

Mój plik nie zostało to załatwione:

name1 
name2 
name3 
name2 
name2 
name3 
name1 

Dlatego zdarzenia nie były następujące siebie i uniq nie działa, ponieważ daje:

1 name1 
1 name2 
1 name3 
2 name2 
1 name3 
1 name1 

ze skryptem awk Jednakże:

name1:2 
name2:3 
name3:2