32blogby StudioMitsu

Guía práctica de sed y awk: el dúo clásico del procesamiento de texto

Domina sed (sustitución, eliminación, inserción) y awk (extracción de columnas, agregación) con ejemplos prácticos.

10 min read
sedawkCLILinuxbashtext-processing
Contenido

"Necesito reemplazar valores masivamente en archivos de configuración." "Quiero extraer columnas específicas de un CSV y calcular totales." "Necesito eliminar ciertas líneas de un archivo de log."

Estos son escenarios clásicos de procesamiento de texto donde sed y awk brillan. Ambos son comandos filtro diseñados para pipelines, pero cada uno destaca en cosas distintas.

Este artículo te guía a través de los fundamentos de sed y awk, patrones prácticos y cómo combinarlos en flujos de trabajo potentes.

sed y awk: ¿Cuál es la diferencia?

Aquí tienes un resumen rápido.

sedawk
Nombre completoStream EditorPattern scanning and processing language
FortalezaTransformación de texto orientada a líneas (sustitución, eliminación, inserción)Procesamiento de datos orientado a columnas (extracción, cálculo, agregación)
Modelo mental"Reescribir texto""Extraer datos del texto"
Uso típicoActualizaciones de archivos de config, limpieza de logsAgregación de CSV/TSV, análisis de logs de acceso

Ambos son comandos filtro de pipeline conectados con |. sed destaca en transformación, awk destaca en extracción y cálculo. Mantén esta distinción en mente y siempre sabrás a cuál recurrir.

Fundamentos de sed

sed — el "editor de flujo" — lee texto línea por línea, aplica transformaciones y devuelve el resultado.

Sustitución

La operación más común es el comando s (sustituir).

bash
# Reemplazar la primera coincidencia en cada línea
sed 's/old/new/' file.txt

# Reemplazar todas las coincidencias en cada línea (flag g)
sed 's/old/new/g' file.txt

# Editar el archivo en su lugar (opción -i)
sed -i 's/old/new/g' file.txt

Selección de líneas y rangos

bash
# Sustituir solo en la línea 3
sed '3s/old/new/' file.txt

# Sustituir en las líneas 2 a 5
sed '2,5s/old/new/g' file.txt

# Sustituir solo en la última línea
sed '$s/old/new/' file.txt

Eliminación, inserción e impresión

bash
# Eliminar líneas que coincidan con un patrón
sed '/pattern/d' file.txt

# Insertar una línea después de la coincidencia
sed '/pattern/a\nueva línea' file.txt

# Insertar una línea antes de la coincidencia
sed '/pattern/i\nueva línea' file.txt

# Imprimir solo un rango específico de líneas (-n suprime la salida por defecto)
sed -n '10,20p' file.txt

Operaciones múltiples y delimitadores personalizados

bash
# Ejecutar múltiples sustituciones en una pasada
sed -e 's/foo/bar/g' -e 's/baz/qux/g' file.txt

# Usar un delimitador alternativo (útil para rutas y URLs)
sed 's|/usr/local|/opt|g' config.txt

El delimitador puede ser cualquier carácter — |, #, @, etc. Esto elimina la necesidad de escapar / al trabajar con rutas de archivos.

sed en la práctica

Actualizaciones masivas de archivos de configuración

Un escenario común durante migraciones de servidor o despliegues.

bash
# Actualizar DB_HOST en un archivo .env
NEW_HOST="db-prod.example.com"
sed -i "s/DB_HOST=.*/DB_HOST=${NEW_HOST}/" .env

# Comentar una línea
sed -i 's/^PermitRootLogin yes/# PermitRootLogin yes/' /etc/ssh/sshd_config

# Descomentar una línea
sed -i 's/^# *PermitRootLogin/PermitRootLogin/' /etc/ssh/sshd_config

Limpieza de archivos de log

bash
# Eliminar líneas vacías
sed '/^$/d' file.txt

# Eliminar espacios al inicio y al final
sed 's/^[[:space:]]*//;s/[[:space:]]*$//' file.txt

# Eliminar secuencias de escape ANSI (códigos de color)
sed 's/\x1b\[[0-9;]*m//g' colored-output.txt

Operaciones por lotes con find

bash
# Reemplazar el año en todos los archivos .txt del proyecto
find . -name "*.txt" -exec sed -i 's/2025/2026/g' {} +

# Generar .env desde .env.example reemplazando valores
sed 's/DB_PASSWORD=changeme/DB_PASSWORD=s3cur3P@ss/' .env.example > .env

Fundamentos de awk

awk procesa texto a nivel de campo (columna). Cada línea se divide automáticamente por espacios en blanco, y los campos son accesibles como $1, $2, etc.

Ten en cuenta que gawk 5.4.0 cambió el motor de regex por defecto a MinRX, que es totalmente compatible con POSIX. Los patrones que dependan de extensiones regex específicas de GNU pueden comportarse de forma diferente. Para usar el motor antiguo, establece la variable de entorno GAWK_GNU_MATCHERS=1.

Extracción de columnas

bash
# Imprimir la 1ª y 3ª columna
awk '{print $1, $3}' data.tsv

# Especificar un delimitador (para CSV)
awk -F',' '{print $1, $2}' data.csv

# Imprimir la línea completa ($0 es la línea entera)
awk '{print $0}' file.txt

Coincidencia de patrones y condiciones

bash
# Imprimir solo líneas que contienen "error"
awk '/error/ {print $0}' logfile.txt

# Imprimir líneas donde la 3ª columna supera 100
awk '$3 > 100 {print $1, $3}' data.txt

# Combinar múltiples condiciones
awk '$3 > 100 && $2 == "active" {print $1, $3}' data.txt

Variables integradas

awk proporciona varias variables integradas útiles.

VariableSignificado
NRNúmero de línea actual (Number of Records)
NFNúmero de campos en la línea actual (Number of Fields)
FSSeparador de campos de entrada (Field Separator)
OFSSeparador de campos de salida
bash
# Imprimir con números de línea
awk '{print NR": "$0}' file.txt

# Mostrar el conteo de campos de cada línea
awk '{print NR": "NF" campos"}' data.txt

# Imprimir el último campo
awk '{print $NF}' data.txt

Bloques BEGIN / END y agregación

bash
# Añadir encabezado y pie
awk 'BEGIN {print "Nombre,Puntuación"} {print $1","$3} END {print "---fin---"}' data.txt

# Sumar la 2ª columna
awk '{sum += $2} END {print "Total:", sum}' sales.txt

# Calcular el promedio
awk '{sum += $2; count++} END {print "Promedio:", sum/count}' sales.txt

Salida formateada con printf

bash
# Alinear a la izquierda 20 chars, a la derecha 10 chars con 2 decimales
awk '{printf "%-20s %10.2f\n", $1, $3}' data.txt

printf usa los mismos especificadores de formato que C. Es invaluable cuando necesitas salida tabular bien alineada.

awk en la práctica

Agregación de datos CSV/TSV

bash
# Totales de ventas por categoría (usando arrays asociativos)
# Entrada: CSV con categoría,producto,cantidad
awk -F',' '{
    sales[$1] += $3
}
END {
    for (cat in sales)
        printf "%-15s %10.0f\n", cat, sales[cat]
}' sales.csv
bash
# Calcular máximo, mínimo y promedio en una pasada
awk 'BEGIN {max = -999999; min = 999999}
{
    sum += $2
    count++
    if ($2 > max) max = $2
    if ($2 < min) min = $2
}
END {
    printf "Máx: %.2f  Mín: %.2f  Prom: %.2f\n", max, min, sum/count
}' data.txt

Análisis de logs de acceso

bash
# Top 10 direcciones IP por número de peticiones
awk '{count[$1]++} END {for (ip in count) print count[ip], ip}' access.log | sort -rn | head -10
bash
# Desglose de códigos de estado HTTP
# Formato CLF: IP - - [fecha] "método ruta proto" estado tamaño
awk '{print $9}' access.log | sort | uniq -c | sort -rn

Salida formateada

bash
# Mostrar información de usuarios en formato tabla
awk -F':' 'BEGIN {
    printf "%-20s %-6s %-6s %s\n", "USUARIO", "UID", "GID", "HOME"
    printf "%-20s %-6s %-6s %s\n", "-------", "---", "---", "----"
}
$3 >= 1000 && $3 < 65534 {
    printf "%-20s %-6s %-6s %s\n", $1, $3, $4, $6
}' /etc/passwd

Combinar sed y awk

sed y awk alcanzan su máximo potencial cuando se canalizan juntos. El patrón típico es sed para preprocesamiento (formateo, filtrado) seguido de awk para agregación.

bash
# Eliminar la fila de encabezado de un CSV, luego sumar la 3ª columna
sed '1d' sales.csv | awk -F',' '{sum += $3} END {print "Total:", sum}'
bash
# Extraer líneas ERROR de un log, luego mostrar solo la marca de tiempo y el mensaje
sed -n '/ERROR/p' app.log | awk '{print $1, $2, substr($0, index($0,$5))}'
bash
# Extraer usuarios con bash de /etc/passwd y formatear la salida
grep '/bash$' /etc/passwd | awk -F':' '{printf "%-15s UID=%-6s %s\n", $1, $3, $6}'
bash
# Contar errores de hoy en syslog por servicio
sed -n "/$(date '+%b %e')/p" /var/log/syslog | awk '/error|fail/ {count[$5]++} END {for (s in count) print count[s], s}' | sort -rn

Alternativa moderna: sd

sd es una alternativa a sed escrita en Rust. Comparado con la sintaxis s/old/new/g de sed, sd requiere menos escape y se lee más naturalmente.

Instalación

bash
# En un entorno WSL, igual que Linux
cargo install sd

Uso básico

bash
# Reemplazar vía stdin
echo "hello world" | sd 'world' 'earth'

# Editar un archivo en su lugar
sd 'old' 'new' file.txt

Comparación sed vs sd

Operaciónsedsd
Reemplazo básicosed 's/foo/bar/g'sd 'foo' 'bar'
Reemplazo de rutassed 's|/usr/local|/opt|g'sd '/usr/local' '/opt'
Grupos regexsed 's/\(foo\)/[\1]/g'sd '(foo)' '[$1]'
Edición en lugarsed -i 's/foo/bar/g' filesd 'foo' 'bar' file

sd usa regex estilo PCRE por defecto, así que no hay necesidad de escapar \( \). Los reemplazos de rutas también funcionan sin cambiar el delimitador.

bash
# Coincidencia multi-línea (v1.1.0+)
sd --across 'start\n.*\nend' 'replaced' file.txt

Si ya te sientes cómodo con sed, no hay necesidad de cambiar. Sin embargo, para one-liners donde el escape de regex se vuelve confuso, sd reduce significativamente la posibilidad de errores. Una regla práctica: usa sd para reemplazos simples, quédate con sed para direccionamiento de líneas y scripts complejos.

Conclusión

sed y awk son el dúo clásico del procesamiento de texto.

  • sed — Sustitución, eliminación e inserción orientada a líneas. Perfecto para actualizaciones de configuración y limpieza de logs
  • awk — Extracción, cálculo y agregación orientada a columnas. Ideal para procesamiento de CSV/TSV y análisis de logs de acceso
  • sed + awk — Canalízalos juntos para preprocesamiento seguido de agregación. sed da forma, awk calcula
  • sd — Una alternativa moderna para cuando la sintaxis de sed se vuelve difícil de manejar. Menos escape, one-liners más limpios

Ambas herramientas tienen casi 50 años de historia y están instaladas en cada sistema Linux. Empieza con el comando s de sed y el {print $1} de awk, luego construye tu repertorio de patrones desde ahí.

Para búsqueda de texto, combínalos con grep y ripgrep. Para procesamiento de JSON, consulta jq. Y para una visión general de todas las herramientas CLI, consulta el Kit de herramientas CLI.