Manual de Awk: Guía Completa para Procesamiento de Texto

Introducción a AWK

AWK es una herramienta poderosa para el procesamiento y análisis de archivos de texto. Fue diseñada para manipular datos estructurados, como archivos de registro o tablas. AWK procesa automáticamente el texto de entrada, dividiendo cada línea en campos y realizando operaciones sobre ellos.

La herramienta AWK se encarga automáticamente de muchas tareas, como la lectura de cada línea de entrada, la división de campos, la gestión de memoria y la inicialización de variables. En AWK, no es necesario declarar los tipos de datos de las variables, ya que el lenguaje incorpora tipos de cadena y numéricos.

Sintaxis básica

La sintaxis básica de AWK es:

awk [opciones] 'script' var=valor archivo(s)

o

awk [opciones] -f archivo_script var=valor archivo(s)

Ejemplo práctico

Supongamos que queremos encontrar todos los usuarios en el sistema que utilizan el shell bash en el archivo /etc/passwd:

awk -F':' '$7 == "/bin/bash"{print "Usuarios con bash shell: ",$1}' /etc/passwd

Este comando AWK realiza las siguientes acciones:

  • -F':': Utiliza el carácter de dos puntos como separador de campos.
  • $7 == "/bin/bash": Filtra las líneas donde el séptimo campo es igual a "/bin/bash".
  • {print "Usuarios con bash shell: ",$1}: Imprime el primer campo (nombre de usuario) junto con un mensaje descriptivo.
  • /etc/passwd: Es el archivo de entrada que se procesará.

Si el archivo /etc/passwd contiene:

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
usuario_prueba:x:1000:1000:usuario_prueba:/home/usuario_prueba:/bin/bash

El resultado será:

Usuarios con bash shell: root
Usuarios con bash shell: usuario_prueba

Nota importante: Si la acción es print $1 $5, los campos se concatenarán porque el espacio en blanco es el carácter de concatenación en AWK. Por ejemplo, nombre = "abc" "bcd" es equivalente a nombre="abcbcd".

Opciones y parámetros

AWK ofrece numerosas opciones para personalizar su comportamiento:

  • -F o --field-separator: Especifica el separador de campos. Por defecto utiliza espacios o tabuladores.
  • -v o --assign: Define una variable y le asigna un valor.
  • -f o --file: Especifica un archivo de script AWK.
  • -W o --word-regexp: Durante la coincidencia de patrones, solo coincide con palabras completas, no con fragmentos.
  • -i o --ignore-case: Ignora mayúsculas y minúsculas durante la coincidencia.
  • -h o --help: Muestra información de ayuda sobre AWK.
  • -Wlint: Habilita el modo de advertencia para detectar problemas potenciales en los scripts AWK.
  • -Wposix: Habilita el modo de compatibilidad POSIX.
  • -Wsource: Muestra el código fuente del script AWK.

Flujo de trabajo

El procesamiento de AWK se divide en tres fases principales:

  1. Bloque BEGIN: Código que se ejecuta antes de procesar el archivo de entrada.
  2. Bloque principal: Código que se ejecuta para cada línea del archivo de entrada.
  3. Bloque END: Código que se ejecuta después de procesar todo el archivo.

La sintaxis general es:

awk 'BEGIN{acciones} patrón{acciones} END{acciones}'

El flujo de trabajo es el siguiente:

  1. Se ejecuta el bloque BEGIN.
  2. Se inicia el porcesamiento del cuerpo del script.
  3. Se leen los registros (líneas) separados por saltos de línea.
  4. Cada registro se divide en campos según el separador especificado. $0 representa el registro completo (línea), $1 el primer campo, $n el n-ésimo campo.
  5. Para cada línea, se ejecuta el código del bloque si el patrón coincide.
  6. El proceso se repite para todas las líneas hasta el final del archivo.
  7. Finalmente, se ejecuta el bloque END para mostrar resultados finales o realizar tareas de limpieza.

Patrones de procesamiento

  • /patrón/{acciones}: Las acciones se ejecutan solo para las líneas que coinciden con el patrón.
  • expresión1,expresión2{acciones}: Define un rango desde la línea que cumple expresión1 hasta la que cumple expresión2.

Formato de salida: print y printf

AWK ofrece dos comandos para mostrar resultados:

  • print: Realiza una salida simple pero no permite formatear el resultado.
  • printf: Permite un control detallado del formato de salida.

Diferencias entre print y printf

  • printf requiere especificar un formato de salida.
  • El formato determina cómo se mostrarán cada uno de los elementos siguientes.
  • printf no añade automáticamente un salto de línea; debe especificarse con \n.
  • print añade un salto de línea automáticamente al final.

Ejemplos de uso

Supongamos que tenemos un archivo de prueba llamado datos.txt con el siguiente contenido:

valor1 valor2 valor3 valor4 valor5 
valor6 valor7 valor8 valor9 valor10 
valor11 valor12 valor13 valor14 valor15

Podemos usar AWK para formatear la salida:

# Mostrar toda la línea sin formato
awk '{printf $0}' datos.txt

# Mostrar cada línea en una nueva línea
awk '{printf "%s\n", $0}' datos.txt

# Formatear la salida con etiquetas
awk '{printf "Primer campo: %s   Segundo campo: %s   Tercer campo: %s\n", $1, $2, $3}' datos.txt

Separadores de campo

AWK permite especificar separadores de campo de diversas formas:

  • -F " ": Por defecto, comprime todos los espacios en blanco iniciales, incluyendo tabuladores y espacios.
  • -F " :": Cuando un espacio va seguido de dos puntos, se usa como separador. Comprime espacios eniciales pero no tabuladores.
  • -F " ": Representa un solo espacio sin comprimir ningún espacio en blanco.
  • -F "|": Especifica la barra vertical como separador.
  • -F ",[ \t]|[ \t]+": Comas seguidas de cero o más espacios, o solo uno o más espacios, se usan como separadores.

Variables integradas

AWK proporciona varias variables integradas:

  • ARGV: Array de parámetros de línea de comandos, indexados desde 0 hasta ARGC-1.
  • ARGC: Número de elementos en el array ARGV.
  • FILENAME: Nombre del archivo actualmente en procesamiento.
  • FNR: Número de registro en el archivo actual (file record number).
  • NR: Número total de registros procesados. No se reinicia al procesar múltiples archivos.
  • NF: Número total de campos en el registro actual (field number).
  • FS: Separador de campos de entrada. Por defecto es espacio en blanco.
  • OFS: Separador de campos de salida. Por defecto es espacio en blanco.
  • RS: Separador de registros de entrada. Por defecto es "\n".
  • ORS: Separador de registros de salida. Por defecto es "\n".
  • OFMT: Formato para convertir números a cadenas en printf. Por defecto es "%.6g".
  • RLENGTH: Longitud de la cadena coincidente con la función match.
  • RSTART: Posición inicial de la cadena coincidente con la función match.
  • SUBSEP: Separador de subíndices. Por defecto es "\034".

Funciones integradas

Funicones matemáticas

  • cos(x): Devuelve el coseno de x.
  • sin(x): Devuelve el seno de x.
  • sqrt(x): Devuelve la raíz cuadrada de x.
  • rand(): Devuelve un número aleatorio r, donde 0 ≤ r < 1.
  • srand(x): Establece la semilla para rand() como x. La misma semilla produce los mismos resultados.
  • int(x): Devuelve la parte entera de x.

Funciones de cadena

  • index(str1, str2): Devuelve la posición de la primera aparición de str2 en str1. Si no se encuentra, devuelve 0.
  • length(str1): Devuelve la longitud de str1. Si no se especifica str1, calcula la longitud de "$0".
  • substr(str1, p): Devuelve el sufijo de str1 comenzando en la posición p.
  • substr(str1, p, n): Devuelve un substring de str1 comenzando en la posición p con longitud n.
  • match(str1, regexp): Si regexp coincide con str1, devuelve la posición inicial. Establece RSTART y RLENGTH.
  • split(str1, array, sep): Divide str1 usando el separador sep y almacena los resultados en array. Devuelve el número de elementos.
  • sprintf(fmt, expr): Devuelve una cadena formateada según fmt a partir de expr.
  • sub(regexp, rep, str2): Reemplaza la primera coincidencia de regexp en str2 con rep. Devuelve 1 si tuvo éxito.
  • gsub(regexp, rep, str2): Reemplaza todas las coincidencias de regexp en str2 con rep. Devuelve el número de reemplazos.
  • toupper(str): Convierte str a mayúsculas.
  • tolower(str): Convierte str a minúsculas.

Variables personalizadas

Es posible definir variables propias en AWK:

awk -v variable="valor" 'NR==1{printf "%d %s\n", variable, $0}' archivo.txt

Este ejemplo asigna el valor "valor" a la variable "variable" y la utiliza en el script.

Funciones personalizadas

AWK permite definir funciones propias:

function nombre(lista-parámetros) {
    declaraciones
}

Las funciones personalizadas permiten modularizar el código y reutilizar lógica común.

Estructuras de control

AWK soporte estructuras de control estándar:

Condicionales

if (expresión) declaraciones
if (expresión) declaraciones else declaraciones

Bucles

while (expresión) declaraciones
for (expresión; expresión; expresión) declaraciones
for (expresión in array) declaraciones
do declaraciones while (expresión)

Control de flujo

  • break: Sale del bucle actual.
  • continue: Pasa a la siguiente iteración del bucle.
  • next: Lee la siguiente línea y reinicia la ejecución del script desde el principio.
  • exit código: Termina la ejecución e ingresa al bloque END. Si ya está en END, sale directamente.

Ejemplos de estructuras

# Condicional con patrón
/patrón/{if (condición){comando1; comando2;}else {comando3; comando4}}

# Condicional con bloque
/patrón/{
   if (condición){
      comando1
      comando2
   }
   else
      comando3
}

# Bucle while
/patrón/{
   comando1
   while (condición){
      comando2
      comando3
   }
}

# Bucle do-while
/patrón/{
   do{
      comando1
      comando2
   } while (condición)
}

# Bucle for
/patrón/{
   for (i=1; i<=10; i++){
      comando1
      comando2
   }
}

Etiquetas: AWK procesamiento de texto scripting linux utilidades de línea de comandos

Publicado el 6-6 21:43