Tengo un archivo de registro ordenado por direcciones IP, quiero encontrar el número de ocurrencias de cada dirección IP única. ¿Cómo puedo hacer esto con bash? Posiblemente enumere el número de ocurrencias junto a una ip, como:
5.135.134.16 count: 5
13.57.220.172: count 30
18.206.226 count:2y así.
Aquí hay una muestra del registro:
5.135.134.16 - - [23/Mar/2019:08:42:54 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
5.135.134.16 - - [23/Mar/2019:08:42:55 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
5.135.134.16 - - [23/Mar/2019:08:42:55 -0400] "POST /wp-login.php HTTP/1.1" 200 3836 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
5.135.134.16 - - [23/Mar/2019:08:42:55 -0400] "POST /wp-login.php HTTP/1.1" 200 3988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
5.135.134.16 - - [23/Mar/2019:08:42:56 -0400] "POST /xmlrpc.php HTTP/1.1" 200 413 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:05 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:06 -0400] "POST /wp-login.php HTTP/1.1" 200 3985 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:07 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:08 -0400] "POST /wp-login.php HTTP/1.1" 200 3833 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:09 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:11 -0400] "POST /wp-login.php HTTP/1.1" 200 3836 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:12 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:15 -0400] "POST /wp-login.php HTTP/1.1" 200 3837 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.220.172 - - [23/Mar/2019:11:01:17 -0400] "POST /xmlrpc.php HTTP/1.1" 200 413 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
13.57.233.99 - - [23/Mar/2019:04:17:45 -0400] "GET / HTTP/1.1" 200 25160 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36"
18.206.226.75 - - [23/Mar/2019:21:58:07 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "https://www.google.com/url?3a622303df89920683e4421b2cf28977" "Mozilla/5.0 (Windows NT 6.2; rv:33.0) Gecko/20100101 Firefox/33.0"
18.206.226.75 - - [23/Mar/2019:21:58:07 -0400] "POST /wp-login.php HTTP/1.1" 200 3988 "https://www.google.com/url?3a622303df89920683e4421b2cf28977" "Mozilla/5.0 (Windows NT 6.2; rv:33.0) Gecko/20100101 Firefox/33.0"
18.213.10.181 - - [23/Mar/2019:14:45:42 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
18.213.10.181 - - [23/Mar/2019:14:45:42 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
18.213.10.181 - - [23/Mar/2019:14:45:42 -0400] "GET /wp-login.php HTTP/1.1" 200 2988 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0"
                    
                        command-line
                                bash
                                sort
                                uniq
                                
                    
                    
                        j0h
fuente
                
                fuente

sort -Vaunque creo que no fue necesario. Envié los 10 principales abusadores de la página de inicio de sesión al administrador del sistema con recomendaciones para prohibir las subredes respectivas. por ejemplo, una IP golpeó la página de inicio de sesión más de 9000 veces. esa IP, y su subred de clase D ahora está en la lista negra. Estoy seguro de que podríamos automatizar esto, aunque esa es una pregunta diferente.Respuestas:
Puede usar
grepyuniqpara la lista de direcciones, recorrerlas ygrepnuevamente para el recuento:grep -o '^[^ ]*'genera cada carácter desde el principio (^) hasta el primer espacio de cada línea,uniqelimina las líneas repetidas y le deja una lista de direcciones IP. Gracias a la sustitución de comandos, elforbucle recorre esta lista imprimiendo la IP procesada actualmente seguida de "conteo" y el conteo. Este último se calcula porgrep -c, que cuenta el número de líneas con al menos una coincidencia.Ejecución de ejemplo
fuente
uniq -coawksolo necesitan leer el archivo una vez,<log grep ...y nogrep ... log?Puedes usar
cutyuniqherramientas:Explicacion:
cut -d ' ' -f1: extraer el primer campo (dirección IP)uniq -c: informa líneas repetidas y muestra el número de ocurrenciasfuente
sed, por ejemplo,sed -E 's/ *(\S*) *(\S*)/\2 count: \1/'para obtener la salida exactamente como OP quería.sort file | cut ....en caso de que no esté seguro de si el archivo ya está ordenado.Si no requiere específicamente el formato de salida dado, recomendaría la respuesta basada en + ya publicada
cutuniqSi realmente necesita el formato de salida dado, una forma de paso único para hacerlo en Awk sería
Esto es algo no ideal cuando la entrada ya está ordenada, ya que almacena innecesariamente todas las IP en la memoria; una forma mejor, aunque más complicada, de hacerlo en el caso previamente ordenado (más directamente equivalente a
uniq -c) sería:Ex.
fuente
Aquí hay una posible solución:
file.logcon el nombre real del archivo.$(awk '{print $1}' "$IN_FILE" | sort -u)proporcionará una lista de los valores únicos de la primera columna.grep -ccontará cada uno de estos valores dentro del archivo.fuente
printf...Algunos Perl:
Esta es la misma idea que el enfoque awk de Steeldriver , pero en Perl. Las
-acausas perl para dividir automáticamente cada línea de entrada en la matriz@F, cuyo primer elemento (la IP) es$F[0]. Entonces,$k{$F[0]}++creará el hash%k, cuyas claves son las IP y cuyos valores son la cantidad de veces que se vio cada IP. El}{es funky perlspeak para "hacer el resto al final, después de procesar todas las entradas". Entonces, al final, el script iterará sobre las claves del hash e imprimirá la clave actual ($_) junto con su valor ($k{$_}).Y, para que la gente no piense que Perl te obliga a escribir guiones que parecen garabatos crípticos, esto es lo mismo en una forma menos condensada:
fuente
Quizás esto no sea lo que quiere el OP; sin embargo, si sabemos que la longitud de la dirección IP se limitará a 15 caracteres, se puede lograr una forma más rápida de mostrar los recuentos con direcciones IP únicas de un archivo de registro enorme utilizando
uniqsolo el comando:Opciones:
-w Nno compara más queNcaracteres en líneas-cprefijará líneas por el número de ocurrenciasAlternativamente, para la salida con formato exacto que prefiero
awk(también debería funcionar para direcciones IPV6), ymmv.Tenga en cuenta que
uniqno detectará líneas repetidas en el archivo de entrada si no son adyacentes, por lo que puede ser necesario parasortel archivo.fuente
FWIW, Python 3:
Salida:
fuente
Explicación: Tome el primer campo de división my.log en guiones
-y ordénelo .uniqnecesita entrada ordenada.-cle dice que cuente las ocurrencias.fuente