Valencia, 2/09/2026, G.B.
Cuando administramos servidores web como Apache, Nginx o LiteSpeed, los archivos de acceso (access.log) se convierten rápidamente en la fuente principal para identificar tráfico no deseado, bots malintencionados o intentos de fuerza bruta.
Aunque existen herramientas de análisis y cortafuegos dinámicos, en muchas ocasiones necesitamos realizar una limpieza rápida de un archivo de log directamente desde la consola, sin instalar dependencias adicionales ni recurrir a lenguajes externos como Python o Perl.
La herramienta clave: grep en modo extendido
grep. En lugar de buscar lo que queremos conservar, le indicamos lo que queremos excluir mediante el parámetro -v.Para manejar rangos o múltiples patrones en una sola pasada, utilizaremos dos modificadores esenciales:
-v(--revert-match): Invierte el resultado de la búsqueda, conservando únicamente las líneas que no coinciden con el patrón.-E(--extended-regexp): Activa las expresiones regulares extendidas, permitiéndonos usar operadores lógicos como la barra vertical (|) para el condicional «O» (OR) y corchetes[]para rangos numéricos.
Filtrado de rangos IP mediante Expresiones Regulares
/24), las utilidades del Shell procesan el archivo de log como texto plano. Por ello, traduciremos las subredes a expresiones regulares fijas.| Rango deseado | Expresión Regular | Explicación |
Subred /24 completa | 192\.168\.1\. | Coincide con cualquier IP que comience por 192.168.1. |
Subred /16 completa | 10\.0\. | Coincide con cualquier IP que empiece por 10.0. |
Rango .0 a .9 | 172\.16\.0\.[0-9] | Filtra del 172.16.0.0 al 172.16.0.9 |
Rango .10 a .99 | 172\.16\.0\.[1-9][0-9] | Filtra del 172.16.0.10 al 172.16.0.99 |
Rango .100 a .199 | 172\.16\.0\.1[0-9][0-9] | Filtra del 172.16.0.100 al 172.16.0.199 |
Nota: Es fundamental escapar los puntos (\.) con una barra invertida. De lo contrario, en expresiones regulares el punto actuaría como un comodín que representa cualquier carácter.
El Script Bash: filtrar_log.sh
#!/bin/bash
# ==============================================================================
# Script de filtrado de IPs y rangos en logs de acceso
# Publicado en Indaga.net
# ==============================================================================
# Validar que se introduzcan los argumentos necesarios
if [ "$#" -ne 2 ]; then
echo "Error: Argumentos insuficientes."
echo "Uso: $0 <log_origen> <log_destino>"
exit 1
fi
LOG_ORIGEN="$1"
LOG_DESTINO="$2"
# Verificar la existencia del archivo de origen
if [ ! -f "$LOG_ORIGEN" ]; then
echo "Error: El archivo '$LOG_ORIGEN' no existe."
exit 1
fi
# Definición de reglas y rangos a excluir (formato Regex)
PATRONES=(
"192\.168\.1\." # Subred 192.168.1.0/24
"10\.0\." # Subred 10.0.0.0/16
"172\.16\.0\.[0-9]" # IPs del 172.16.0.0 al 172.16.0.9
"172\.16\.0\.1[0-9]" # IPs del 172.16.0.10 al 172.16.0.19
"203\.0\.113\.45" # Dirección IP única estática
)
# Unir el array de patrones utilizando la barra vertical (|) como separador OR
PATRON_REGEX=$(IFS='|'; echo "${PATRONES[*]}")
# Ejecución del filtrado con grep
grep -v -E "$PATRON_REGEX" "$LOG_ORIGEN" > "$LOG_DESTINO"
# Confirmación de salida
if [ $? -eq 0 ]; then
echo "Filtrado completado con éxito."
echo "Archivo limpio guardado en: $LOG_DESTINO"
else
echo "Ocurrió un error al procesar el archivo."
fi
Modo de empleo
- Guardar el archivo: Crea el script en tu servidor, por ejemplo con
nano filtrar_log.sh. - Asignar permisos de ejecución:
chmod +x filtrar_log.sh - Ejecutar el proceso: Pasa como primer argumento el log actual y como segundo el nombre del archivo resultante:
./filtrar_log.sh /var/log/nginx/access.log /var/log/nginx/access_limpio.log
Ejecución rápida en una sola línea (One-Liner)
grep -v -E "192\.168\.1\.|10\.0\.|172\.16\.0\.[0-9]" access.log > access_filtrado.log
