Contando el número de veces que cada dirección IP aparece en el archivo de registro

9

Tengo un archivo en el siguiente formato:

$ 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

¿Cuál es la mejor manera de analizar el archivo file.txten un formato como:

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

En otras palabras, quiero recorrer el archivo y contar la cantidad de veces que aparece cada dirección IP. Ya lo he revisado sortpara que todas las direcciones IP estén en orden y directamente una tras otra.

James Spittal
fuente
Yo, personalmente, importaría este tipo de archivo en una práctica base de datos cercana (al crear una tabla temporal en cualquier instancia de postgres que tenga), seguido de una acción rápida de SQL y exportar de nuevo a un archivo de texto.
Oakad

Respuestas:

23

Estas buscando uniq -c

Si el resultado no es de su agrado, puede analizarse y formatearse fácilmente.

Por ejemplo:

$ 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
Glenn Jackman
fuente
Combinar uniqy awkno parece ser un gran enfoque para mí ...
Hauke ​​Laging
3
Porque uniqsolo funciona en entradas ordenadas (coincide con líneas coincidentes adyacentes, no con ninguna línea del archivo).
Oakad
1
Debe ordenar los resultados antes de canalizarlos a uniq. Si lees la Q original, el OP dice que ya ha ordenado los resultados sort.
slm
2
@HaukeLaging: agradezco lo que dices, pero de la misma manera que la mayoría de los usuarios de computadoras nunca se aventurarán más allá de OSX y Windows, aún más, la mayoría de los usuarios de Unix no se aventurarán más allá del uso de herramientas designadas para tareas específicas. Usar AWK no es para los débiles de corazón, mire lo que tenía que hacer para realizar esta tarea básica usando AWK versus lo que requería la solución de Glenn. Creo que estoy siendo justo al decir que es una solución más simple para comprender mentalmente, aunque la suya es probablemente más eficiente. Por cierto, hice UV ambos ya que ambos son correctos!
slm
1
@HaukeLaging: sí, exactamente. A medida que se pasea por el sitio, nuestras responsabilidades cambian ligeramente, IMO. Somos responsables de hacer A'ers integrales y mirar los A'ers que proporcionamos como momentos de enseñanza para el OP y cada visitante futuro que se encuentre con él, nuevamente en la OMI. Pero es una elección personal, por lo que si solo tiene unos minutos de sobra, siempre se agradece proporcionar una A en cualquier forma.
slm
6

uniqparece ser la solución más inteligente, de hecho. La manera awk:

awk '{ip_count[$0]++}; '\
'END {for (ip in ip_count) printf "%15s: %d\n",ip,ip_count[ip];}' file
Hauke ​​Laging
fuente
+1. Si el orden de la salida es importante para el OP, esta respuesta no garantiza: la iteración sobre las claves de una matriz asociativa no tiene un orden inherente.
Glenn Jackman
@glennjackman Pero agregar sorta mi respuesta es aún más rápido ya que hay que ordenar menos elementos. ;-)
Hauke ​​Laging
¿Oh si? ¿¡¿OH SI?!? ;) la entrada ya está ordenada. Esta respuesta awk los baraja, por lo que aún es más trabajo. Nyah! ;)
Glenn Jackman
0

archivo de clasificación más rápido y luego contar por unic -c

sort filename | uniq -c

Aeyd Moeyd
fuente
1
El archivo ya está ordenado (según el usuario en la pregunta), y uniq -cfuncionaría pero proporcionaría la salida en el formato incorrecto. Esta es la razón por la cual la respuesta aceptada no usa sorty en su lugar formatea la salida de uniq -c.
Kusalananda
Gracias @Aeyd. Estaba buscando este comando. Ayuda
user11392987
0

Yo usaría python. Todos los sistemas Linux actualmente tienen python2 instalado.

Agregue cada dirección IP a un dict (matriz asociativa) como pares clave = valor, es decir, {"12.34.56.78": 1, "87.76.43.21": 3}.

Usted 'verifica' la dirección IP como una clave e incrementa el valor en 1. Si usa defaultdict ("ip"), si la clave no existe, se crea con un valor predeterminado de 0. Si la clave existe ya, defaultdict no hace nada. El valor se incrementa en la siguiente línea.

#!/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")

archivo de salida:

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

Sé que estaba buscando una solución de línea de comando, pero como puede ver, es una pantalla con formato elegante que solo tomó una docena de líneas más o menos. Python es una excelente herramienta para la administración.

Mike Childers
fuente