Tutorial de awk: separadores, patrones, variables y ejemplos prácticos awk

Tutorial de awk: separadores, patrones, variables y ejemplos prácticos

DUGLAS MORENODUGLAS MORENO 👁 43

Introducción

Awk es una de esas herramientas clásicas de Unix que sigue siendo indispensable para cualquiera que trabaje con texto estructurado: logs, CSV, archivos de configuración o cualquier lista de datos en columnas. Si tenés que extraer información, hacer cálculos simples o transformar columnas sin escribir un script completo en Python o Bash, awk suele ser la solución más rápida y ligera.

Este tutorial está dirigido a desarrolladores, administradores de sistemas y analistas de datos que ya manejan la línea de comandos y quieren profundizar en el uso de awk. Aprenderás a definir separadores de campo, a combinar patrones y acciones, a aprovechar variables integradas como NR, NF, FS y OFS, y a aplicar todo eso en ejemplos concretos: sumar columnas, extraer datos específicos, cambiar el formato de salida y más. Cada script incluye la salida esperada para que puedas verificarlo al instante.

Al final, tendrás un repertorio de patrones que podés copiar y pegar en tu terminal, además de una base sólida para explorar funciones más avanzadas de awk.


¿Qué es awk y cómo se invoca?

Awk interpreta cada línea de entrada como un registro y la divide en campos según un separador (por defecto, cualquier secuencia de espacios o tabs). Luego vos podés especificar un patrón (una condición) y una acción (qué hacer cuando el patrón coincide). La sintaxis básica es:

awk 'patrón { acción }' archivo

Si el patrón se omite, la acción se ejecuta en todas las líneas. Si la acción se omite, awk simplemente imprime la línea completa (equivalente a { print $0 }).

Los comandos se pueden pasar directamente entre comillas simples para que el shell no interprete los signos como caracteres especiales. Dentro de esas comillas simples podés usar comillas dobles para cadenas si las necesitás, pero en la mayoría de los ejemplos vamos a evitarlas.


Definiendo el separador de campo

El separador determina cómo awk corta cada línea en campos $1, $2, $3 … $NF. Hay dos formas principales:

1. Usando la variable interna FS

FS (Field Separator) se puede asignar dentro del script, por ejemplo en un bloque BEGIN:

awk 'BEGIN { FS = 	 } { print $1, $3 }' datos.txt

Esto establece el separador como tabulador antes de procesar cualquier línea.

2. Con la opción -F de la línea de comandos

Es más cómodo para pruebas rápidas:

awk -F',' '{ print $2 }' archivo.csv

Aquí el separador es la coma, ideal para archivos CSV simples.

3. Expresiones regulares como separador

FS también puede ser una regex. Por ejemplo, para separar por uno o más espacios o tabs:

awk 'BEGIN { FS = "[ 	]+" } { print $1 }' datos.txt

Nota: dentro de BEGIN usamos comillas dobles para que el shell no rompa la cadena; pero como el script completo está entre comillas simples, esas comillas dobles son parte del código awk y no necesitan escape extra.


Variables integradas más usadas

Awk provee varias variables que se actualizan automáticamente. Conocerlas te permite escribir scripts más breves y expresivos.

| Variable | Significado | Ejemplo
|----------|-------------|
| NR | Número de registro (número de línea leída, empieza en 1)
| NF | Número de campos en el registro actual
| FS | Separador de campo de entrada (ver arriba)
| OFS | Separador de campo de salida (por defecto, un espacio)
| RS | Separador de registro (por defecto, salto de línea)
| ORS | Separador de registro de salida (por defecto, salto de línea)
| FILENAME | Nombre del archivo que se está procesando

Un caso típico: imprimir número de línea y cantidad de campos:

awk '{ print NR, NF, $0 }' archivo.txt

Salida esperada (asumiendo que archivo.txt tiene tres líneas con 4, 2 y 5 campos respectivamente):

1 4 linea con cuatro campos
2 2 linea con dos campos
3 5 otra linea con cinco campos

Patrones y acciones

El patrón puede ser una expresión regular, una comparación, un rango o incluso la palabra especial BEGIN/END. La acción es un bloque de código entre llaves.

Patrones simples

  • Coincidencia exacta de campo: $2 == "activo"
  • Comparación numérica: $3 > 1000
  • Expresión regular: $0 ~ /error/ (la línea contiene la palabra error)
  • Rango de líneas: NR >= 10 && NR <= 20 (líneas del 10 al 20)

Acciones comunes

  • print o printf para salida
  • Asignaciones: $1 = toupper($1)
  • Acumuladores: sum += $4
  • Salida a archivo: print > "resultado.txt"

Ejemplo 1: Sumar una columna

Supongamos que tenés un archivo ventas.txt con el formato:

producto cantidad precio
manzana 10 0.5
banana 5 0.3
cereza 2 1.2

Queremos calcular el ingreso total (cantidad * precio).

awk '{ ingreso = $2 * $3; total += ingreso } END { printf "Ingreso total: %.2f
", total }' ventas.txt

Explicación:

  • En cada línea calculamos el ingreso y lo vamos acumulando en la variable total.
  • En el bloque END (que se ejecuta después de leer todo el archivo) imprimimos el total con dos decimales.

Salida esperada:

Ingreso total: 11.40

Ejemplo 2: Extraer columnas específicas y cambiar el separador de salida

Imaginemos un CSV de empleados:

id,nombre,departamento,sueldo
1,Ana,Contabilidad,3500
2,Luis,IT,4200
3,María,Contabilidad,3800

Queremos obtener solo el nombre y el sueldo, separados por punto y coma (;).

awk -F',' 'NR>1 { print $2 \); OFS=\ \); print $2, $4 }' empleados.csv

Espera, ahí cometimos un error: vamos a corregirlo. La forma correcta es definir OFS antes de usar print:

awk -F',' 'BEGIN { OFS = \); } NR>1 { print $2, $4 }' empleados.csv
  • -F',' establece la coma como separador de entrada.
  • En BEGIN fijamos OFS a );.
  • NR>1 excluye la cabecera.
  • print $2, $4 muestra el segundo y cuarto campo separados por OFS.

Salida esperada:

Ana;3500
Luis;4200
María;3800

Ejemplo 3: Filtrar líneas con un patrón y contar coincidencias

Queremos saber cuántas líneas del archivo log.txt contienen la palabra "FAIL" (mayúsculas o minúsculas).

awk 'tolower($0) ~ /fail/ { contador++ } END { print "Fallos encontrados:" , contador }' log.txt
  • tolower($0) convierte la línea completa a minúsculas para que la búsqueda sea case‑insensitive.
  • Cada coincidencia incrementa contador.
  • En END mostramos el total.

Supongamos que log.txt tiene:

[INFO] Operación completada
[WARN] Posible retraso
[ERROR] FAIL en módulo auth
[INFO] Reiniciando servicio
[ERROR] fail de red

Salida esperada:

Fallos encontrados: 2

Ejemplo 4: Cambiar el separador de registro (RS) para procesar bloques

Algunos archivos tienen registros separados por líneas en blanco. Por ejemplo, un bloque de datos de sensores donde cada bloque termina con una línea en blanco.

Contenido de sensores.dat:

Temp: 23.5
Hum: 45
Pres: 1013

Temp: 22.1
Hum: 48
Pres: 1010

Temp: 23.9
Hum: 44
Pres: 1012

Queremos imprimir la temperatura y la humedad de cada bloque, una línea por bloque.

awk -v RS='' '{ gsub(/
/, " \); print $2, $4 }' sensores.dat

Explicación:

  • -v RS='' le indica a awk que el separador de registro es una línea en blanco (dos saltos de línea seguidos). Así cada bloque se convierte en un registro.
  • Dentro del registro, los saltos de línea siguen siendo caracteres; los reemplazamos por espacios con gsub(/ /, " \) para que los campos se separen por espacios.
  • Después de la sustitución, $2 es el valor de Temperatura y $4 el de Humedad.

Salida esperada:

23.5 45
22.1 48
23.9 44

Ejemplo 5: Uso de variables definidas por el usuario

Awk permite crear variables propias. Vamos a calcular el promedio de una columna y mostrar cuántos valores están por encima del promedio.

Archivo notas.txt:

85
92
78
90
88
awk '{ suma += $1; count++ } END { promedio = suma / count; supra = 0; for (i=1; i<=count; i++) if (valor[i] > promedio) supra++; print "Promedio:" promedio; print "Valor(es) arriba del promedio:" supra }' notas.txt

Espera, estamos usando un arreglo valor que no hemos llenado. Vamos a reescribir el script correctamente:

awk '{ suma += $1; valores[NR] = $1; count++ } END { promedio = suma / count; supra = 0; for (i=1; i<=count; i++) if (valores[i] > promedio) supra++; printf "Promedio: %.2f
Valor(es) arriba del promedio: %d
", promedio, supra }' notas.txt
  • Guardamos cada valor en el arreglo valores indexado por NR.
  • Después de leer todo, calculamos el promedio.
  • Recorremos el arreglo contando cuántos superan el promedio.

Salida esperada:

Promedio: 86.60
Valor(es) arriba del promedio: 3

Buenas prácticas y errores comunes

Buenas prácticas

  1. Usar comillas simples alrededor del script awk para evitar que el shell expanda variables o caracteres especiales.
  2. Definir FS y OFS en BEGIN cuando necesites cambiarlos; así se aplican a todo el procesamiento y evitas sorpresas.
  3. Preferir printf sobre print cuando necesites controlar el formato (número de decimales, ancho de campo, etc.).
  4. Acumular en bloques END para resultados globales (sumas, promedios, conteos).
  5. Comprobar NF antes de acceder a campos si el archivo podría tener líneas con formato variable, por ejemplo:
    awk 'NF >= 3 { accion }' archivo
    
  6. Usar variables descriptivas en lugar de nombres genéricos como x o y; mejora la legibilidad.
  7. Probar con archivos pequeños primero antes de ejecutar sobre grandes volúmenes de datos.

Errores comunes

  • Olvidar que el separador de salida (OFS) afecta a todas las impresiones; si lo cambias en medio del script, todas las siguientes print lo usarán.
  • Confundir NR (número de registro) con FNR (número de registro dentro del archivo actual) cuando se procesan varios archivos; FNR se reinicia en cada archivo.
  • Asumir que FS solo puede ser un solo carácter; recuerda que puede ser una expresión regex, lo que permite separadores múltiples.
  • No inicializar variables de acumulación; si usas total += $2 sin darle un valor inicial, awk lo trata como cero en la primera uso, pero en algunos contextos (como dentro de funciones) puede causar valores inesperados.
  • Usar $0 dentro de un bloque BEGIN; en BEGIN todavía no se ha leído ningún registro, así que $0 está vacío.

Conclusión

Awk sigue siendo una herramienta poderosa para procesar datos de columna a columna sin salir de la terminal. Ahora sabes cómo:

  • Definir el separador de campo con -F o la variable FS.
  • Aprovechar variables integradas como NR, NF, OFS y RS para controlar la entrada y la salida.
  • Combinar patrones y acciones para filtrar, transformar y resumir información.
  • Aplicar todo esto en ejemplos reales: sumar columnas, extraer datos, cambiar formato de salida y trabajar con bloques de registros separados por líneas en blanco.

Con estos conceptos podés resolver la mayoría de las tareas de extracción y cálculo rápido que aparecen en el día a día de un desarrollador o administrador. La próxima vez que te enfrentes a un log o a un CSV, pensá en awk antes de abrir un editor o escribir un script más largo.

¡A practicar! Probá los ejemplos con tus propios archivos y modificá los scripts para adaptarlos a tus necesidades. Cuanto más los uses, más natural te resultará pensar en términos de registros, campos y patrones.


¿Te quedó alguna duda? Dejála en los comentarios y con gusto te ayudo a afinar tu awk.

Comentarios (0)

Sé el primero en comentar.

Dejá tu comentario