AWK y SED Avanzado
AWK y SED son herramientas fundamentales para el procesamiento de texto en Linux. Esta guía cubre desde conceptos básicos hasta técnicas avanzadas para análisis de logs, manipulación de datos y tareas de pentesting.
SED - Stream Editor
Section titled “SED - Stream Editor”SED es un editor de flujo que permite realizar transformaciones básicas en texto de manera eficiente.
Sintaxis Básica
Section titled “Sintaxis Básica”sed [opciones] 'comando' archivosed [opciones] -e 'comando1' -e 'comando2' archivoComandos Básicos de SED
Section titled “Comandos Básicos de SED”Sustitución (s)
Section titled “Sustitución (s)”# Sustitución básica (primera ocurrencia)sed 's/old/new/' archivo.txt
# Sustitución global (todas las ocurrencias)sed 's/old/new/g' archivo.txt
# Sustitución case-insensitivesed 's/old/new/gi' archivo.txt
# Usar diferentes delimitadoressed 's|/path/old|/path/new|g' archivo.txtsed 's#old#new#g' archivo.txt
# Sustitución con backreferencessed 's/\([0-9]*\)/Number: \1/g' archivo.txt
# Sustitución condicional (solo en líneas que coincidan)sed '/pattern/s/old/new/g' archivo.txtEliminación (d)
Section titled “Eliminación (d)”# Eliminar líneas específicassed '3d' archivo.txt # Línea 3sed '2,5d' archivo.txt # Líneas 2 a 5sed '$d' archivo.txt # Última línea
# Eliminar líneas que coincidan con patrónsed '/pattern/d' archivo.txt
# Eliminar líneas vacíassed '/^$/d' archivo.txt
# Eliminar líneas que empiecen con #sed '/^#/d' archivo.txtInserción y Adición
Section titled “Inserción y Adición”# Insertar antes de línea específicased '3i\Nueva línea' archivo.txt
# Agregar después de línea específicased '3a\Nueva línea' archivo.txt
# Insertar antes de patrónsed '/pattern/i\Nueva línea' archivo.txt
# Agregar después de patrónsed '/pattern/a\Nueva línea' archivo.txtTécnicas Avanzadas de SED
Section titled “Técnicas Avanzadas de SED”Múltiples comandos
Section titled “Múltiples comandos”# Múltiples comandos con -esed -e 's/old1/new1/g' -e 's/old2/new2/g' archivo.txt
# Múltiples comandos con punto y comased 's/old1/new1/g; s/old2/new2/g' archivo.txt
# Script de SEDcat > script.sed << 'EOF's/old1/new1/gs/old2/new2/g/^#/dEOFsed -f script.sed archivo.txtRangos y patrones
Section titled “Rangos y patrones”# Aplicar comando en rango de líneassed '2,5s/old/new/g' archivo.txt
# Desde patrón hasta línea específicased '/start/,10s/old/new/g' archivo.txt
# Entre dos patronessed '/start/,/end/s/old/new/g' archivo.txt
# Desde línea específica hasta el finalsed '5,$s/old/new/g' archivo.txtHold space y pattern space
Section titled “Hold space y pattern space”# Intercambiar líneas (h, g, x)sed -n '1h;2g;p' archivo.txt
# Agregar línea siguiente al pattern spacesed -n 'N;s/\n/ /;p' archivo.txt
# Imprimir línea anteriorsed -n 'x;p;g;h' archivo.txtAWK - Pattern Scanning and Processing
Section titled “AWK - Pattern Scanning and Processing”AWK es un lenguaje de programación completo para procesamiento de texto estructurado.
Sintaxis Básica
Section titled “Sintaxis Básica”awk 'pattern { action }' archivoawk -F'delimiter' 'program' archivoEstructura de AWK
Section titled “Estructura de AWK”# Estructura completaawk 'BEGIN { # Código de inicialización}/pattern/ { # Código para líneas que coincidan}{ # Código para todas las líneas}END { # Código de finalización}' archivoVariables Integradas
Section titled “Variables Integradas”# Variables principalesNR # Número de registro (línea) actualNF # Número de campos en la línea actualFS # Separador de campos (por defecto: espacio)OFS # Separador de campos de salidaRS # Separador de registros (por defecto: nueva línea)ORS # Separador de registros de salidaFILENAME # Nombre del archivo actualEjemplos Básicos de AWK
Section titled “Ejemplos Básicos de AWK”Procesamiento de campos
Section titled “Procesamiento de campos”# Imprimir campos específicosawk '{print $1, $3}' archivo.txt
# Imprimir último campoawk '{print $NF}' archivo.txt
# Imprimir penúltimo campoawk '{print $(NF-1)}' archivo.txt
# Cambiar separador de camposawk -F':' '{print $1, $3}' /etc/passwd
# Múltiples separadoresawk -F'[,:]' '{print $1, $2}' archivo.txtPatrones y condiciones
Section titled “Patrones y condiciones”# Líneas que coincidan con patrónawk '/pattern/ {print}' archivo.txt
# Líneas que NO coincidanawk '!/pattern/ {print}' archivo.txt
# Condiciones numéricasawk '$3 > 100 {print}' archivo.txt
# Condiciones de stringawk '$1 == "admin" {print}' archivo.txt
# Múltiples condicionesawk '$1 == "admin" && $3 > 100 {print}' archivo.txtProgramación Avanzada en AWK
Section titled “Programación Avanzada en AWK”Variables y arrays
Section titled “Variables y arrays”# Variables definidas por usuarioawk '{sum += $3} END {print "Total:", sum}' archivo.txt
# Arrays asociativosawk '{count[$1]++} END {for (i in count) print i, count[i]}' archivo.txt
# Array multidimensionalawk '{arr[$1,$2] = $3} END {for (key in arr) print key, arr[key]}' archivo.txtFunciones integradas
Section titled “Funciones integradas”# Funciones de stringawk '{print length($1)}' archivo.txt # Longitudawk '{print substr($1, 2, 3)}' archivo.txt # Substringawk '{print toupper($1)}' archivo.txt # Mayúsculasawk '{print tolower($1)}' archivo.txt # Minúsculasawk '{gsub(/old/, "new", $1); print}' archivo.txt # Sustitución global
# Funciones matemáticasawk '{print sqrt($1)}' archivo.txt # Raíz cuadradaawk '{print int($1)}' archivo.txt # Enteroawk '{print rand()}' archivo.txt # Número aleatorioControl de flujo
Section titled “Control de flujo”# Condicionalesawk '{ if ($3 > 100) print "Alto:", $1 else if ($3 > 50) print "Medio:", $1 else print "Bajo:", $1}' archivo.txt
# Buclesawk '{ for (i = 1; i <= NF; i++) print "Campo " i ": " $i}' archivo.txt
# While loopawk '{ i = 1 while (i <= NF) { print $i i++ }}' archivo.txtEjemplos para Pentesting y Análisis
Section titled “Ejemplos para Pentesting y Análisis”Análisis de Logs de Apache/Nginx
Section titled “Análisis de Logs de Apache/Nginx”# Top 10 IPs por número de requestsawk '{print $1}' access.log | sort | uniq -c | sort -nr | head -10
# Códigos de estado HTTPawk '{print $9}' access.log | sort | uniq -c | sort -nr
# URLs más solicitadasawk '{print $7}' access.log | sort | uniq -c | sort -nr | head -20
# Requests por horaawk '{print substr($4, 2, 11)}' access.log | sort | uniq -c
# User agents sospechososawk -F'"' '{print $6}' access.log | sort | uniq -c | sort -nr
# Detectar posibles ataquesawk '$7 ~ /\.\.|\/etc\/|\/proc\/|union|select|script/ {print $1, $7}' access.logAnálisis de Logs del Sistema
Section titled “Análisis de Logs del Sistema”# Errores SSH por IPawk '/Failed password/ {print $(NF-3)}' /var/log/auth.log | sort | uniq -c | sort -nr
# Intentos de login por usuarioawk '/Failed password/ {print $9}' /var/log/auth.log | sort | uniq -c | sort -nr
# Conexiones exitosas SSHawk '/Accepted password/ {print $9, $11}' /var/log/auth.log
# Análisis de logs de firewallawk '/DROP/ {print $12}' /var/log/kern.log | sed 's/SRC=//' | sort | uniq -c | sort -nrProcesamiento de Archivos de Configuración
Section titled “Procesamiento de Archivos de Configuración”# Extraer usuarios del sistemaawk -F':' '$3 >= 1000 {print $1, $5}' /etc/passwd
# Servicios activosawk '/^[^#]/ && NF > 0 {print $1}' /etc/services | sort | uniq
# Configuración de redawk '/inet / {print $2}' <(ip addr show)
# Procesos por usuariops aux | awk '{user[$1] += $3} END {for (u in user) print u, user[u]}'Análisis de Tráfico de Red
Section titled “Análisis de Tráfico de Red”# Análisis de netstatnetstat -an | awk '$1 == "tcp" && $6 == "ESTABLISHED" {print $5}' | cut -d: -f1 | sort | uniq -c
# Conexiones por puertonetstat -an | awk '$1 == "tcp" {print $4}' | cut -d: -f2 | sort | uniq -c | sort -nr
# Análisis de tcpdumptcpdump -n | awk '{print $3}' | cut -d. -f1-4 | sort | uniq -c | sort -nrScripts Avanzados
Section titled “Scripts Avanzados”Script de análisis de logs completo
Section titled “Script de análisis de logs completo”#!/bin/bashLOG_FILE=${1:-/var/log/apache2/access.log}
echo "=== ANÁLISIS DE LOG: $LOG_FILE ==="
echo -e "\n--- Top 10 IPs ---"awk '{print $1}' "$LOG_FILE" | sort | uniq -c | sort -nr | head -10
echo -e "\n--- Códigos de Estado ---"awk '{status[$9]++} END { for (code in status) printf "%-3s: %d\n", code, status[code]}' "$LOG_FILE" | sort
echo -e "\n--- URLs Sospechosas ---"awk '$7 ~ /\.\.|\/etc\/|\/proc\/|union|select|<script/ { printf "%-15s %s\n", $1, $7}' "$LOG_FILE" | head -20
echo -e "\n--- Requests por Hora ---"awk '{ time = substr($4, 2, 14) gsub(/:/, " ", time) hour = substr(time, 1, 13) requests[hour]++} END { for (h in requests) printf "%s: %d\n", h, requests[h]}' "$LOG_FILE" | sortScript de monitoreo de procesos
Section titled “Script de monitoreo de procesos”#!/bin/bashps aux | awk 'BEGIN { printf "%-10s %-8s %-8s %-8s %s\n", "USER", "CPU%", "MEM%", "PID", "COMMAND" printf "%-10s %-8s %-8s %-8s %s\n", "----", "----", "----", "---", "-------"}NR > 1 { if ($3 > 5.0 || $4 > 5.0) { printf "%-10s %-8.1f %-8.1f %-8s %s\n", $1, $3, $4, $2, $11 }}END { print "\nProcesos con alto uso de recursos (>5%)"}'Generador de reportes de seguridad
Section titled “Generador de reportes de seguridad”#!/bin/bashecho "=== REPORTE DE SEGURIDAD $(date) ==="
echo -e "\n--- Intentos de Login Fallidos ---"awk '/Failed password/ { ip = $(NF-3) user = $9 attempts[ip][user]++} END { for (ip in attempts) { for (user in attempts[ip]) { if (attempts[ip][user] > 5) { printf "IP: %-15s Usuario: %-10s Intentos: %d\n", ip, user, attempts[ip][user] } } }}' /var/log/auth.log
echo -e "\n--- Conexiones de Red Sospechosas ---"netstat -an | awk '$1 == "tcp" && $6 == "ESTABLISHED" { split($5, remote, ":") ip = remote[1] port = remote[2] if (port == "22" || port == "23" || port == "3389") { printf "Conexión sospechosa: %s:%s\n", ip, port }}'
echo -e "\n--- Archivos Modificados Recientemente ---"find /etc -type f -mtime -1 -exec ls -la {} \; | awk '{ printf "%-20s %s %s %s\n", $9, $6, $7, $8}'Técnicas de Optimización
Section titled “Técnicas de Optimización”Rendimiento de SED
Section titled “Rendimiento de SED”# Usar -n con p para imprimir solo líneas específicassed -n '10,20p' archivo.txt
# Salir después de encontrar patrónsed '/pattern/q' archivo.txt
# Procesar solo las primeras N líneassed '100q' archivo.txtRendimiento de AWK
Section titled “Rendimiento de AWK”# Salir temprano cuando sea posibleawk '/pattern/ {print; exit}' archivo.txt
# Usar next para saltar procesamientoawk '/skip/ {next} {print}' archivo.txt
# Procesar solo campos necesariosawk '{print $1, $3}' archivo.txt # Más rápido que procesar todos los camposCasos de Uso Específicos
Section titled “Casos de Uso Específicos”Limpieza de datos
Section titled “Limpieza de datos”# Eliminar líneas duplicadas manteniendo ordenawk '!seen[$0]++' archivo.txt
# Normalizar espacios en blancosed 's/[[:space:]]\+/ /g' archivo.txt
# Eliminar caracteres no imprimiblessed 's/[^[:print:]]//g' archivo.txt
# Convertir CSV a formato tabularawk -F',' '{printf "%-20s %-15s %-10s\n", $1, $2, $3}' archivo.csvTransformación de formatos
Section titled “Transformación de formatos”# JSON simple a CSVawk -F'"' '/"name":/ {name=$4} /"value":/ {value=$4; print name","value}' data.json
# Log de Apache a formato personalizadoawk '{printf "%s|%s|%s|%s\n", $1, $4, $7, $9}' access.log
# Convertir timestampsawk '{ cmd = "date -d @" $1 " +\"%Y-%m-%d %H:%M:%S\"" cmd | getline formatted_date close(cmd) print formatted_date, $2, $3}' timestamps.txtNota de Rendimiento: Para archivos muy grandes, considera usar herramientas especializadas como
mawk(más rápido quegawk) oGNU parallelpara procesamiento en paralelo. AWK y SED son extremadamente eficientes para la mayoría de tareas de procesamiento de texto.