Linux en Español

30 ejemplos para el comando Awk en el procesamiento de texto

En la publicación anterior hablamos del comando sed y observamos la utilidad del mismo, pero este comando tienes algunas limitaciones. A veces necesitas algo poderoso, que te dé más control al momento de procesar datos. Aquí es donde entra el comando awk.

El comando awk o GNU awk en específico proporciona un lenguaje de scripting para el procesamiento de texto. Con el lenguaje de scripting awk puedes:


  • Definir variables.
  • Utilizar cadenas y operadores aritméticos.
  • Utilizar control de flujo y ciclos.
  • Generar reportes con formato.

Actualmente, puedes procesar archivos de registro que contengan tal vez millones de líneas de salida, a un reporte del cual te puedes beneficiar.

 

 

Opciones del comando awk

El comando awk es utilizado de la siguiente manera:

$ awk options program file

Awk puede tomar las siguientes opciones:

-F fs     Para especificar un separador de archivos.

-f file     Para especificar un archivo que contenga un script awk.

-v var=value     Para declarar una variable.

Vamos a ver como procesar archivos e imprimir resultados utilizando awk.

 

Leer Scripts AWK

Para definir un script awk utilizamos llaves rodeadas por unas comillas simples como se muestra a continuación:

$ awk '{print "Welcome to awk command tutorial "}'

awk command

Si escribes cualquier cosa, retornara la misma cadena de bienvenida que nosotros proporcionamos.

Para terminar el programa, presiona Ctrl+D. Parece complicado, pero no entres en pánico, lo mejor está por venir.

 

Utilizando Variables

Con awk puedes procesar archivos de texto. Awk asigna algunas variables para cada campo de datos encontrado:

  • $0 para toda la línea.
  • $1 para el primer campo.
  • $2 para el segundo campo.
  • $n para el campo enésimo campo.

Los caracteres de espacio en blanco como el espacio o la tabulación es el separador por defecto entre los campos en el awk.

Ahora observa este ejemplo y mira como awk lo procesa::

$ awk '{print $1}' myfile

awk command variables

El ejemplo anterior imprime la primera palabra de cada línea.

Algunas veces el separador en algunos archivos no es el espacio ni la tabulación, sino algo más. Puedes especificarlo utilizando la opción – F:

$ awk -F: '{print $1}' /etc/passwd

awk command passwd

Este comando imprime el primer campo en el archive passwd. Utilizamos los dos puntos como separador porque el archivo passwd lo utiliza.

 



Utilizando Múltiples Comandos

Para ejecutar múltiples comandos, sepáralos con un símbolo de punto y coma de la siguiente forma:

$ echo "Hello Tom" | awk '{$2="Adam"; print $0}'

awk multiple commands

El primer comando hace que el campo $2 sea equivalente a Adam. El segundo comando imprime la línea completa.

 

Leyendo el Script Desde un Archivo

Puedes escribir tu script awk en un archivo y especificar ese archive utilizando la opción –f.

Nuestro archive contiene este script:

{print $1 " home at " $6}

$ awk -F: -f testfile /etc/passwd

awk command read from file

Aquí imprimimos el nombre de usuario y su ruta inicial desde /etc/passwd, y en este caso el separador es especificado con la letra mayúscula -F el cual es los dos puntos.

Puedes utilizar tu archivo script de la siguiente forma:

$ awk -F: -f testfile /etc/passwd

awk command multiple commands


Pre procesamiento Awk

Si necesitas crear un título o cabecera para tu resultado. Puedes utilizar la palabra clave BEGIN para lograr esto. Esta se ejecutará antes de procesar los datos:

$ awk 'BEGIN {print "Report Title"}'

Vamos a aplicárselo a algo más y observemos el resultado:

awk command begin command

 

Post Procesamiento Awk

Para ejecutar un script después de procesar los datos, utiliza la palabra clave END:

awk command end command

Esto es muy útil si quieres agregar un footer a tu ejemplo.

A continuación, combinemos ambos en un archivo de script:

Primero, la sección superior es creada utilizando BEGIN. Luego definimos FS e imprimimos el footer al final.

$ awk -f myscript  /etc/passwd

awk command complete script

 

Variables Integradas

Hemos visto que las variables de campo de datos $1, $2 $3, etc son utilizadas para extraer datos del campo, además debemos lidiar con el separador FS.

Pero estas no son las únicas variables, existen más variables integradas.

a continuación, en la siguiente lista se muestran algunas de las variables:

FIELDWIDTHS     especifica el ancho del campo.

RS     Especifica el separador de registros.

FS     Especifica un separador de campos.

OFS  Especifica un separador de Salidas.

ORS  Especifica el separador de Salidas.

Por defecto, la variable OFS es el espacio, puedes establecer esta variable para que especifique el separador que necesitas:

$ awk 'BEGIN{FS=":"; OFS="-"} {print $1,$6,$7}' /etc/passwd

awk command builtin variables

A veces, los campos son distribuidos sin un separador fijo. En estos casos, la variable FIELDWIDTHS resuelve este problema.

Supongamos que tenemos este contenido:

$ awk 'BEGIN{FIELDWIDTHS="3 4 3"}{print $1,$2,$3}' testfile

awk command field width

Ahora mira la salida. Esta salida tiene 3 campos por línea y la longitud de cada campo viene dada por lo que asignamos en FIELDWIDTH.

Como siguiente ejercicio supongamos que tus datos son distribuidos en líneas diferentes como se muestra a continuación:

En el ejemplo anterior, awk falla al procesar los campos debido a que estos son separados por el carácter de nueva línea y no el de espacio.

Necesitas establecer la variable FS con el carácter de nueva línea (\n) y la RS a texto en blanco, de manera que las líneas vacías sean consideradas separadores.

$ awk 'BEGIN{FS="\n"; RS=""} {print $1,$3}' addresses

awk command field separator

¡Impresionante! Ahora podemos leer los registros y campos apropiadamente.

 

Mas Variables

Existen otras variables que puede ayudarte a obtener más información:

ARGC     Retorna el número de parámetros pasados.

ARGV     Retorna los parámetros de la línea de comandos.

ENVIRON     Es un arreglo de las variables de ambiente del shell y sus respectivos valores.

FILENAME    El nombre del archive que está siendo procesado por awk.

NF     Cuenta los campos de la línea que está siendo procesada.

NR    Retorna el total de registros procesados.

FNR     Con esta variable puedes acceder al registro que está siendo procesado.

IGNORECASE     Le dice al programa que ignore las diferencias entre mayúsculas y minúsculas.

Puedes revisar los post anteriores de scripting de shell para conocer más acerca de estas variables.

Vamos a probarlas.

$ awk 'BEGIN{print ARGC,ARGV[1]}' myfile

awk command arguments

La variable ENVIRON retorna las variables de ambiente del shell de la siguiente manera:

awk command data variables

Puedes utilizar variables del bash sin variables del ENVIRON así:

$  echo | awk -v home=$HOME '{print "My home is " home}'

awk shell variables

La variable NF especifica el ultimo campo en el registro sin conocer su posición:

$ awk 'BEGIN{FS=":"; OFS=":"} {print $1,$NF}' /etc/passwd

awk command NF

Esta variable NF puede ser utilizada como una variable de campo de datos si la escribes con esta sintaxis: $NF.

Veamos estos dos ejemplos para conocer la diferencia entre las variables FNR y NR:

$ awk 'BEGIN{FS=","}{print $1,"FNR="FNR}' myfile myfile

awk command FNR

En este ejemplo, el comando awk define dos archivos de entrada. El mismo archivo, pero procesado dos veces. La salida es el calor del primer campo y la variable FNR.

Ahora, revisa la variable NR y mira la diferencia:

awk command NR FNR

La variable FNR se convierte en 1 cuando viene al segundo archivo, pero la variable NR mantiene su valor.

 


Variables Definidas por el Usuario

Los nombres de variables pueden ser cualquiera, pero no puede empezar con un número.

Puedes asignar de la misma forma que en el scripting de shell:

awk command user variables

 

Comandos Estructurados

El lenguaje de scripting awk tiene soporte de sentencias condicionales if.

El archivo de prueba contiene lo siguiente:

10

15

6

33

45

$ awk '{if ($1 > 30) print $1}' testfile

awk command if command

Así de simple.

Debes utilizar llaves si quieres ejecutar múltiples sentencias:

awk command multiple statements

Puedes utilizar sentencias else así:

awk command else

O puedes escribirlas en la misma línea y separar la sentencia if con un punto y coma de esta forma:

awk command else one line

Ciclo While

Puedes utilizar un ciclo while para iterar sobre los datos con una condición.

cat myfile

124 127 130

112 142 135

175 158 245

118 231 147

awk command while loop

El ciclo se ejecuta y cada vez añade 1 a la variable sum hasta que esta se vuelve 4.

Puedes salir del ciclo utilizando el comando break como se muestra a continuación:

awk command break

El ciclo for

El lenguaje de scripting awk soporta sentencias de ciclos for:

awk command for loop

 

Dándole Formato a una Impresión

El comando printf en awk permite que imprimas con un formato de salida utilizando especificadores de formatos.

Los especificadores de formatos son escritos de la siguiente forma:

%[modifier]control-letter

Esta lista muestra cómo se puede utilizar los especificadores de formato con printf:

c              Imprime salidas numéricas como una cadena de caracteres (string).

d             Imprime un valor entero.

e             Imprime números con notación científica.

f              Imprime valores numéricos con decimales (float).

o             Imprime valores en notación octal.

s             Imprime una cadena de texto.

En esta sentencia utilizamos printf para darle formato a nuestra salida:

awk command printf

Aquí podemos ver un ejemplo de impresión de números con notación científica

No vamos a probar todos los especificadores de formato. Ya con esto conoces el concepto.

 


Funciones Integradas

Awk proporciona múltiples funciones integradas como:

Funciones Matemáticas

Si amas las matemáticas, puedes utilizar estas funciones en tus scripts awk:

sin(x) | cos(x) | sqrt(x) | exp(x) | log(x) | rand()

Y estas pueden ser usadas normalmente así:

$ awk 'BEGIN{x=exp(5); print x}'

awk command math functions

Funciones de String (cadenas de caracteres)

Existen muchas funciones de string, puedes buscar la lista en línea, aquí examinaremos una de ellas como ejemplo, el resto siempre serán parecidas:

$ awk 'BEGIN{x = "likegeeks"; print toupper(x)}'

awk command string functions

La función toupper convierte los caracteres del string pasado a mayúsculas.

 

Funciones Definidas por el Usuario

Puedes definir tus propias funciones y utilizarlas como se muestra en el siguiente código:

awk command user defined functions

Aquí definimos una función llamada myprint, luego la utilizamos para imprimir una salida utilizando la función printf.

Espero que te haya gustado la publicación.

Gracias.

Mokhtar Ebrahim
Estoy trabajando como administrador de sistemas Linux desde 2010. Soy responsable de mantener, proteger y solucionar problemas de servidores Linux para múltiples clientes de todo el mundo. Me encanta escribir guiones de shell y Python para automatizar mi trabajo.

2 thoughts on “30 ejemplos para el comando Awk en el procesamiento de texto

  1. hola, a ver si me puedes ayudar, tengo un listado con 7 columnas y una de ellos es una dirección de correo Ej: Pedro;Pérez;30;hombre;soltero;[email protected];23444234
    el listado resultante debo añadir 2 columnas más derivadas del correo, que serían cuenta y dominio. me quedaría así: Pedro;Pérez;30;hombre;soltero;[email protected];23444234;pedroperez;gmail.com

    si solo fuera un listado de correo lo puedo procesar con awk con separador @, pero acá no sé como sería.

    Gracias

    1. ¡Fácil!
      Para obtener el correo electrónico completo, puede usar el siguiente comando:
      $ awk -F\; '{print $6}' myfile
      Luego puede canalizar los resultados nuevamente a AWK para obtener el correo electrónico y el dominio por separado:
      Para recibir correo electrónico:
      $ awk -F\; '{print $6}' myfile | awk [email protected] 'END{for(i in A)print i}{A[$1]++}'
      Para obtener dominio:
      $ awk -F\; '{print $6}' myfile | awk [email protected] 'END{for(i in A)print i}{A[$2]++}'
      Entonces puede enviar la salida a un archivo o a la pantalla.
      Dado que su separador es un punto y coma, debe escapar con barra invertida
      Saludos,

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *