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 ripgrep o dnf 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ónSignificado
-iCoincidencia sin distinción de mayúsculas
-nMostrar números de línea
-cContar líneas coincidentes
-lImprimir solo nombres de archivos que coincidan
-LImprimir archivos SIN coincidencia
-vInvertir — imprimir líneas que no coinciden
-wCoincidencia de palabras completas únicamente
-rRecursar en directorios
-A NMostrar N líneas después de la coincidencia
-B NMostrar N líneas antes de la coincidencia
-C NMostrar N líneas antes y después
--colorResaltar 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ácterSignificadoEjemplo
.Cualquier caráctergr.p coincide con grep, grip
*Cero o más del anteriorgo*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
\bLí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ísticagrepripgrep (rg)ack
Incluido en LinuxNoNo
Velocidad en árboles grandesBuenaExcelenteBuena
Respeta .gitignoreNoParcialmente
Filtros por tipo de archivo--include-t py--python
Color por defectoCon --color
Manejo de archivos binariosOmite o fallaOmisión inteligenteOmite
Archivo de configuraciónNo.ripgreprc~/.ackrc
Mejor paraLogs del sistema, scriptsBúsqueda en códigoBú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, -v son las opciones más usadas
  • El regex básico (BRE) es el predeterminado; usa grep -E para regex extendido con +, ? y |
  • -o extrae solo la parte que coincide — esencial para extracción de datos de logs
  • Combina grep con tail -f para monitoreo de logs en tiempo real
  • Usa grep -F para 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

Artículos Relacionados