Conteggio del numero di volte in cui ciascun indirizzo IP viene visualizzato nel file di registro


9

Ho un file nel formato seguente:

$ cat file.txt

27.33.65.2
27.33.65.2
58.161.137.7
121.50.198.5
184.173.187.1
184.173.187.1
184.173.187.1

Qual è il modo migliore per analizzare il file file.txtin un formato come:

27.33.65.2: 2
58.161.137.7: 1
121.50.198.5: 1
184.173.187.1: 3

In altre parole, voglio scorrere il file e contare il numero di volte in cui appare ciascun indirizzo IP. L'ho già eseguito in sortmodo che tutti gli indirizzi IP siano in ordine e direttamente uno dopo l'altro.


Personalmente, importerei questo tipo di file in un pratico DB vicino (creando una tabella temporanea in qualsiasi istanza di postgres che ho in giro), seguita da una rapida azione SQL ed esportata di nuovo in un file di testo.
Oakad,

Risposte:


23

Stai cercando uniq -c

Se il risultato non è di tuo gradimento, può essere analizzato e riformattato facilmente.

Per esempio:

$ uniq -c logfile.txt | awk '{print $2": "$1}'
27.33.65.2: 2
58.161.137.7: 1
121.50.198.5: 1
184.173.187.1: 3

Combinare uniqe awknon sembra essere un grande approccio per me ...
Hauke ​​Laging,

3
Perché uniqfunziona solo sull'input ordinato (corrisponde alle righe corrispondenti adiacenti, non a tutte le righe del file).
Oakad,

1
È necessario ordinare i risultati prima di inviarli a uniq. Se leggi la Q originale, l'OP afferma che ha già ordinato i risultati usando sort!
slm

2
@HaukeLaging - Apprezzo quello che stai dicendo, ma allo stesso modo in cui la maggior parte degli utenti di computer non si avventurerà mai oltre OSX e Windows, inoltre la maggior parte degli utenti di Unix non si avventurerà oltre l'utilizzo di strumenti designati per attività specifiche. L'uso di AWK non è per i deboli di cuore, guarda cosa hai dovuto fare per eseguire questo compito di base usando AWK rispetto a ciò che la soluzione di Glenn ha richiesto. Penso di essere sincero nel dire che la sua è una soluzione più semplice da afferrare mentalmente, sebbene la tua sia probabilmente più efficiente. A proposito, ho fatto UV entrambi perché sono entrambi corretti!
slm

1
@HaukeLaging - Sì, esattamente. Mentre ti aggiri nel sito, le nostre responsabilità cambiano leggermente, IMO. Siamo responsabili della creazione di A'er globali e della visione degli A'er che forniamo come momenti di insegnamento all'OP e a tutti i futuri visitatori che lo incontrano, di nuovo IMO. Ma è una scelta personale, quindi se hai solo pochi minuti da perdere, è sempre utile fornire una A in qualsiasi forma.
slm

6

uniqsembra essere la soluzione più intelligente, anzi. Il modo strano:

awk '{ip_count[$0]++}; '\
'END {for (ip in ip_count) printf "%15s: %d\n",ip,ip_count[ip];}' file

+1. Se l'ordine dell'output è importante per l'OP, questa risposta non fornisce alcuna garanzia: l'iterazione sulle chiavi di un array associativo non ha un ordine intrinseco.
Glenn Jackman,

@glennjackman Ma l'aggiunta sortalla mia risposta è ancora più veloce in quanto è necessario ordinare meno elementi. ;-)
Hauke ​​Laging

o si? O SI?!? ;) l'ingresso è già ordinato. Questa risposta imbarazzante li mescola, quindi è ancora più lavoro. Nyah! ;)
glenn jackman,

0

file di ordinamento più veloce quindi ottenere il conteggio da unic -c

sort filename | uniq -c


1
Il file è già ordinato (in base all'utente nella domanda) e uniq -cfunzionerebbe ma fornirà l'output nel formato errato. Questo è il motivo per cui la risposta accettata non utilizza sorte riformatta invece l'output di uniq -c.
Kusalananda

Grazie @Aeyd. Stavo cercando questo comando. Aiuta
user11392987

0

Vorrei usare Python. Oggigiorno ogni sistema Linux ha installato python2.

Aggiungi ogni indirizzo IP in un dict (array associativo) come coppie chiave = valore, ovvero {"12.34.56.78": 1, "87.76.43.21": 3}.

Si 'verifica' l'indirizzo IP come chiave e si incrementa il valore di 1. Se si utilizza defaultdict ("ip"), se la chiave non esiste, viene creata con un valore predefinito pari a 0. Se la chiave esiste già defaultdict non fa nulla. Il valore viene incrementato nella riga successiva.

#!/usr/bin/python2

infile = open("file.txt","r")
iplist = {}  # create an empty dict

for line in infile:
    line = line.strip()   # remove newline.
    if line: # if not a blank line.
        iplist.setdefault(line, 0) # check for ip and add with default value of 0
        iplist[line] += 1 # increment

outfile = open("out.txt","w") #open output file

for key in iplist.keys():
    line = "%-15s = %s" % (key, iplist[key])
    print line   # print uf desired.
    outfile.write(line + "\n")

file di ritaglio:

cat out.txt                                                          
27.33.65.2      = 2
58.161.137.7    = 1
121.50.198.5    = 1
184.173.187.1   = 3

So che stavi cercando una soluzione a riga di comando, ma come puoi vedere è un display elegantemente formattato che impiegava solo una dozzina di righe. Python è uno strumento eccellente per l'amministrazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.