2015-01-16 11 views
7
03/03/2014 12:31:21 BLOCK 10.1.34.1 11:22:33:44:55:66 

03/03/2014 12:31:22 ALLOW 10.1.34.2 AA:BB:CC:DD:EE:FF 

03/03/2014 12:31:25 BLOCK 10.1.34.1 55:66:77:88:99:AA 

Sto tentando di utilizzare awk per contare il numero di occorrenze della parola "blocco" e "accesso" sopra in un comando.Utilizzo di awk per contare il numero di occorrenze di una parola in una colonna

Ho provato la parola "blocco" all'inizio, ma il mio contatore non sembra funzionare. Qualcuno può vedere dove il mio codice è sbagliato?

awk ' BEGIN {count=0;} { if ($3 == "BLOCK") count+=1} end {print $count}' firewall.log 
+0

Vuoi dire consentono invece di accesso? –

risposta

19

utilizzare un array

awk '{count[$3]++} END {for (word in count) print word, count[word]}' file 

Se si vuole "blocco" in particolare: END {print count["BLOCK"]}

+0

Ciao, come faccio a grep la base informativa sul conteggio [parola]? Per esempio, se voglio grep la linea che conta [word] è più di 2. @glenn jackman – user3631848

+0

per favore in base alla risposta, grazie – user3631848

+0

Si aggiungerebbe un'istruzione 'if' nel ciclo' for' nel Blocco FINE. –

4

La ragione per cui il codice non può essere al lavoro è END è case sensitive così il vostro script sarà controllando esiste la variabile end (che non è) e quindi l'ultimo blocco non verrà mai eseguito. Se lo cambi, dovrebbe funzionare.

Inoltre non occorre il blocco BEGIN come tutte le variabili sono istanziati a 0.

Qui di seguito ho aggiunto un modo alternativo di fare questo che si consiglia di utilizzare invece.

Questo è simile a quello di glenn ma cattura solo le parole che vuoi, dovrebbe usare poca memoria a causa di questo.


Uso Gawk (per la terza arg incontro)

awk 'match($3,/BLOCK|ALLOW/,b){a[b[0]]++}END{for(i in a)print i ,a[i]}' file 

Questo blocco esegue solo se BLOCK o ALLOW sono contenuti nel terzo campo.
La partita cattura ciò che è stato abbinato nell'array b.
Quindi la matrice a viene incrementata per il campo corrispondente.

Nel blocco END ogni campo acquisito viene emesso con un numero di occorrenze.


L'uscita è

ALLOW 1 
BLOCK 2 
1

L'errore nel vostro awk invocazione è che, nel blocco "END", avete print $count. Questo prende il contenuto della variabile count, presuppone che sia un numero intero e tenta di trovare il campo corrispondente nell'ultima riga di input. Quello che vuoi veramente è solo print count, in quanto stampa semplicemente il valore nella variabile count. A volte è facile mescolare diversi schemi di riferimento variabili tra bash, awk, python, ecc., Quindi è un errore facile da fare.

2

Ecco una soluzione non di codice. Puoi mettere insieme i passaggi con pipe ("|").

cat file | awk '{print $3}' | sort | uniq -c 
  • cat file
    leggere il file e inviarlo a stdout (il programma successivo nel tubo

  • awk '{print $ 3}'
    stampa il 3 ° colonna, il valore predefinito separatore di record in awk è lo spazio bianco

  • ordinamento
    ordinare i risultati

  • uniq -c
    contare il numero ripetuto occorrenze

+2

Prima di tutto, formatta il tuo codice come codice per rendere la tua risposta più leggibile. In secondo luogo, evita le risposte al solo codice, modifica la risposta per spiegare il codice. Informazioni sulle risposte al solo codice, leggi [this] (http://meta.stackoverflow.com/questions/303598/low-quality-but-still-an-answer/303605#303605). –

+0

Grazie per il feedback. –

2

ho testato la sua dichiarazione

awk ' BEGIN {count=0;} { if ($3 == "BLOCK") count+=1} end {print $count}' firewall.log 

ed era in grado di contare con successo BLOCK facendo due modifiche

  1. end dovrebbe essere nei tappi
  2. rimuovere $ da print $count

Quindi, dovrebbe essere:

awk ' BEGIN {count=0;} { if ($3 == "BLOCK") count+=1} END {print count}' firewall.log 

Una dichiarazione più semplice che funziona troppo è:

awk '($3 == "BLOCK") {count++ } END { print count }' firewall.log 
Problemi correlati