De vez en cuando quiero grep rangos CIDR fuera de mis archivos de registro de Apache. Esto es fácil para rangos que caen dentro de los límites naturales (/ 8, / 16 y / 24) pero no es tan fácil para otros rangos como / 17 y / 25.
Ejemplos:
# 192.168.0.0/16: (easy)
grep " 192\.168\." access_log
# 192.168.128.0/17: (more thought required)
grep -E " 192\.168\.(12[89]|1[3-9][0-9]|2[0-5][0-9])\." access_log
# 192.168.0.0/17: (more thought required)
grep -E " 192\.168\.([0-9]|[0-9][0-9]|1[01][0-9]|12[0-7])\." access_log
# 192.168.128.0/18: (straining my brain)
grep -E " 192\.168\.(1[2-8][0-9]|19[01])\." access_log
Estas expresiones regulares ignoran las direcciones IP que incluyen ceros a la izquierda, como 192.168.001.001
, que no es un problema en los archivos de registro de Apache pero podría estar en otros archivos de registro. A las impresoras en particular parece gustarles los ceros iniciales. Es bastante fácil agregar los ceros opcionales a la expresión regular, pero solo hace que todo sea un poco más difícil. Tiene que haber una manera más fácil.
¿Hay una manera fácil de seleccionar líneas de un archivo que coincida con cualquier rango CIDR?
Las extensiones de expresiones regulares de lujo se considerarán al igual que las diferentes herramientas (como awk
o perl
si es necesario, pero quiero que sea de una sola línea) si facilitan el trabajo. Idealmente, lo que me gustaría es algo como
grep "[:CIDR 192.168.128.0/18:]" access_log
Una herramienta que convierte un rango CIDR en la expresión regular apropiada también estaría bien.
$ cidr2regex 192.168.0.0/18
192\.168\.(1[2-8][0-9]|19[01])\.[0-9]{1,3}
o
$ grep -E "$(cidr2regex 192.168.0.0/18)" access_log
Puntos de bonificación si su respuesta también cubre IPv6.