grep es la columna vertebral de la búsqueda de texto en Linux. Ya sea que necesites encontrar una cadena dentro de un archivo de log, filtrar la salida de una tubería, o buscar un patrón en miles de archivos fuente, dominar grep y las expresiones regulares es una de las habilidades más valiosas que puede tener un usuario de Linux o administrador de sistemas. Esta guía cubre desde el uso básico hasta patrones de regex avanzados, escenarios reales de filtrado de logs y una comparación práctica de grep, ripgrep y ack.
Requisitos Previos
- Un sistema Linux (Ubuntu, Debian, CentOS, Arch o similar)
- Familiaridad básica con la terminal (ver Usar la Terminal en Ubuntu)
- grep preinstalado (está en todas las distribuciones de Linux por defecto)
- Opcional: ripgrep (
apt install ripgrepodnf install ripgrep) y ack (apt install ack)
Uso Básico de grep
grep lee uno o más archivos (o entrada estándar) e imprime las líneas que coinciden con un patrón. La forma más simple es:
grep 'patrón' nombre_archivo
Opciones clave que usarás cada día:
| Opción | Significado |
|---|---|
-i | Coincidencia sin distinción de mayúsculas |
-n | Mostrar números de línea |
-c | Contar líneas coincidentes |
-l | Imprimir solo nombres de archivos que coincidan |
-L | Imprimir archivos SIN coincidencia |
-v | Invertir — imprimir líneas que no coinciden |
-w | Coincidencia de palabras completas únicamente |
-r | Recursar en directorios |
-A N | Mostrar N líneas después de la coincidencia |
-B N | Mostrar N líneas antes de la coincidencia |
-C N | Mostrar N líneas antes y después |
--color | Resaltar coincidencia en la salida |
Ejemplos:
# Encontrar todas las líneas con "error" (sin distinguir mayúsculas)
grep -i 'error' /var/log/syslog
# Mostrar números de línea en el resultado
grep -n 'Failed password' /var/log/auth.log
# Contar cuántas veces aparece un patrón
grep -c 'GET /api' access.log
# Buscar recursivamente en todos los archivos .py
grep -r 'import os' --include='*.py' ./proyecto
Expresiones Regulares Básicas (BRE)
Por defecto, grep usa Expresiones Regulares Básicas. Los metacaracteres esenciales:
| Metacarácter | Significado | Ejemplo |
|---|---|---|
. | Cualquier carácter | gr.p coincide con grep, grip |
* | Cero o más del anterior | go*d coincide con gd, god, good |
^ | Inicio de línea | ^ERROR coincide con líneas que empiezan con ERROR |
$ | Fin de línea | \.log$ coincide con líneas que terminan en .log |
\b | Límite de palabra | \bfail\b coincide con fail pero no failure |
[ ] | Clase de caracteres | [aeiou] coincide con cualquier vocal |
[^ ] | Clase negada | [^0-9] coincide con cualquier no-dígito |
\{n,m\} | Rango de repetición | [0-9]\{2,4\} coincide con 2–4 dígitos |
# Líneas que comienzan con una marca de fecha (p.ej., 2026-02-21)
grep '^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}' app.log
# Líneas que terminan con un mensaje de conexión rechazada
grep 'refused$' /var/log/nginx/error.log
Expresiones Regulares Extendidas (ERE) con grep -E
El regex extendido elimina las barras invertidas de los operadores de repetición y agrupación, haciendo los patrones más legibles. Usa grep -E o el alias egrep:
grep -E 'patrón' archivo
Ejemplos prácticos de ERE:
# Coincidir con ERROR, WARN o CRITICAL
grep -E 'ERROR|WARN|CRITICAL' /var/log/app.log
# Coincidir con direcciones IP (simplificado)
grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' access.log
# Coincidir líneas con código de estado HTTP 4xx o 5xx
grep -E ' [45][0-9]{2} ' access.log
# Extraer direcciones de correo electrónico de un archivo
grep -Eo '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' contactos.txt
La opción -o (only/solo) imprime únicamente la parte que coincide, no la línea completa — esencial para extraer datos.
Filtrado de Logs en Tiempo Real
Combina grep con tail -f para monitorear logs en vivo:
# Seguir syslog y mostrar solo líneas de error
tail -f /var/log/syslog | grep -i 'error'
# Mostrar errores de nginx pero excluir el ruido de healthcheck
tail -f /var/log/nginx/access.log | grep -v '/health'
# Resaltar múltiples patrones simultáneamente
tail -f /var/log/app.log | grep --color -E 'ERROR|WARN|INFO'
Las cadenas de tuberías son el caso de uso más poderoso de grep para operaciones:
# Contar inicios de sesión SSH fallidos por IP (últimas 1000 líneas)
tail -1000 /var/log/auth.log \
| grep 'Failed password' \
| grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' \
| sort | uniq -c | sort -rn
Comparativa: grep vs ripgrep vs ack
| Característica | grep | ripgrep (rg) | ack |
|---|---|---|---|
| Incluido en Linux | Sí | No | No |
| Velocidad en árboles grandes | Buena | Excelente | Buena |
| Respeta .gitignore | No | Sí | Parcialmente |
| Filtros por tipo de archivo | --include | -t py | --python |
| Color por defecto | Con --color | Sí | Sí |
| Manejo de archivos binarios | Omite o falla | Omisión inteligente | Omite |
| Archivo de configuración | No | .ripgreprc | ~/.ackrc |
| Mejor para | Logs del sistema, scripts | Búsqueda en código | Búsqueda en código |
Cuándo usar grep: análisis de logs del sistema, scripts de shell, búsquedas puntuales en servidores donde solo tienes herramientas estándar.
Cuándo usar ripgrep: búsqueda en bases de código, pipelines de CI, donde la velocidad importa. Paraleliza la lectura de archivos y usa SIMD para el matching de patrones.
# grep — filtro de inclusión explícito
grep -r 'TODO' --include='*.js' ./src
# ripgrep — igual, con abreviatura de tipo de archivo
rg 'TODO' -t js ./src
# ack — consciente del tipo por defecto
ack --js 'TODO' ./src
Escenario del Mundo Real — Triaje de Logs en Producción
Tienes un servidor web en producción que genera 50 GB de logs al día. Después de una alerta de incidente, necesitas encontrar todas las solicitudes que devolvieron errores 500 entre las 14:00 y 15:00, identificar las más lentas y extraer las IPs únicas de los clientes.
# Paso 1 — aislar la ventana de tiempo
grep '21/Feb/2026:1[4-5]:' /var/log/nginx/access.log > /tmp/ventana.log
# Paso 2 — filtrar solo errores 500
grep -E ' 500 ' /tmp/ventana.log > /tmp/errores_500.log
echo "Total de errores 500 en la ventana: $(wc -l < /tmp/errores_500.log)"
# Paso 3 — extraer y clasificar IPs de clientes
grep -Eo '^[0-9.]+ ' /tmp/errores_500.log \
| sort | uniq -c | sort -rn | head -20
Este pipeline de múltiples pasos reduce 50 GB a datos accionables en segundos.
Errores Comunes y Casos Especiales
Buscar en archivos binarios: grep imprimirá “Binary file matches” y omitirá la salida. Fuerza el modo texto con -a (--text) o usa strings primero.
Caracteres especiales en patrones: Si tu término de búsqueda contiene ., *, [ o \, escápalos con \ o usa grep -F (cadena fija, sin regex). grep -F '1.2.3.4' encuentra puntos literales, no “cualquier carácter”.
Rendimiento en archivos enormes: grep es de un solo hilo. Para archivos de varios GB, considera ripgrep (paralelo) o usa zgrep para logs comprimidos.
Problemas de localización: En algunos sistemas, [a-z] incluye caracteres acentuados dependiendo del locale LC_ALL. Usa LC_ALL=C grep para comportamiento ASCII predecible.
Solución de Problemas
grep devuelve código de salida 1 en scripts: Este es el comportamiento esperado — grep sale con 1 cuando no hay coincidencias, lo que causa que los scripts con set -e se abortan. Usa grep ... || true para manejar esto.
El patrón no coincide a pesar del texto visible: Verifica si hay retornos de carro (\r) en archivos de Windows. Ejecuta grep -P '\r' para detectarlos y dos2unix para eliminarlos.
Búsqueda recursiva lenta: Agrega --exclude-dir=.git (o usa ripgrep que lo hace por defecto) para evitar rastrear el directorio .git.
Resumen
- grep busca en archivos y stdin las líneas que coincidan con un patrón;
-i,-n,-r,-vson las opciones más usadas - El regex básico (BRE) es el predeterminado; usa
grep -Epara regex extendido con+,?y| -oextrae solo la parte que coincide — esencial para extracción de datos de logs- Combina grep con
tail -fpara monitoreo de logs en tiempo real - Usa
grep -Fpara búsquedas de cadenas literales y evitar sorpresas con metacaracteres - ripgrep es más rápido para búsqueda en código; grep sigue siendo rey para logs y scripts