---
title: "Cómo filtrar direcciones IP y rangos en logs Web usando solo Bash"
description: "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..."
url: https://indaga.net/como-filtrar-direcciones-ip-y-rangos-en-logs-web-usando-solo-bash/
date: 2026-09-22
modified: 2026-09-21
author: "Directorio Indaga"
categories: ["GNU Linux", "Recursos y Utilidades"]
tags: ["bash", "blog", "gnu linux", "grep", "linux"]
type: post
lang: es
---

# Cómo filtrar direcciones IP y rangos en logs Web usando solo Bash

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.

En este artículo veremos cómo construir un script en **Bash puro** que nos permita eliminar líneas enteras de un log basándonos en direcciones IP individuales o rangos mediante expresiones regulares (*regex*).

## La herramienta clave: `grep` en modo extendido

Para filtrar contenido en GNU/Linux descartando líneas completas, el comando por excelencia es `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

A diferencia de las herramientas orientadas a red que interpretan notación CIDR (como `/24`), las utilidades del Shell procesan el archivo de log como texto plano. Por ello, traduciremos las subredes a expresiones regulares fijas.
A continuación, algunas equivalencias útiles para definir rangos dentro del patrón de filtrado:

| **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`

A continuación se muestra la estructura completa del script. Este toma como entrada el archivo de log original y genera un nuevo archivo limpio sin las líneas asociadas a las IP definidas.

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

1. **Guardar el archivo:** Crea el script en tu servidor, por ejemplo con `nano filtrar_log.sh`.
2. **Asignar permisos de ejecución:** ``` chmod +x filtrar_log.sh ```
3. **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)

Si no necesitas la estructura del script y buscas solucionar una tarea puntual en la terminal, puedes ejecutar el filtro directamente concatenando los patrones deseados:

```
grep -v -E "192\.168\.1\.|10\.0\.|172\.16\.0\.[0-9]" access.log > access_filtrado.log
```

Esta alternativa utiliza únicamente las utilidades nativas de cualquier sistema POSIX, garantizando un rendimiento óptimo al procesar grandes volúmenes de texto sin sobrecargar los recursos del sistema.
