Cómo usar el lenguaje AWK para manipular texto en Linux

Introducción

Las utilidades de Linux suelen seguir la filosofía de diseño de Unix. Se fomenta que las herramientas sean pequeñas, utilicen archivos de texto sin formato para la entrada y salida, y operen de forma modular. Gracias a este legado, disponemos de una gran funcionalidad de procesamiento de texto con herramientas como sed y awk.

awkEs un lenguaje de programación y procesador de texto que permite manipular datos textuales de forma muy útil. En esta guía, explorarás cómo usar la awkherramienta de línea de comandos y cómo procesar texto.

Sintaxis básica

El awkcomando está incluido de forma predeterminada en todos los sistemas Linux modernos, por lo que no es necesario instalarlo para comenzar a usarlo.

awkEs especialmente útil al gestionar archivos de texto con un formato predecible. Por ejemplo, es excelente para analizar y manipular datos tabulares. Opera línea por línea e itera por todo el archivo.

De forma predeterminada, se utilizan espacios en blanco (tabuladores, etc.) para separar los campos. Afortunadamente, muchos archivos de configuración de Linux utilizan este formato.

El formato básico de un awkcomando es:

awk '/search_pattern/ { action_to_take_on_matches; another_action; }' file_to_parse

Puede omitir la parte de búsqueda o la parte de acción de cualquier awkcomando. Por defecto, la acción que se realiza si no se especifica la parte “acción” es “imprimir”. Esto simplemente imprime todas las líneas que coinciden.

Si no se proporciona la parte de búsqueda, awkrealiza la acción que aparece en cada línea.

Si se proporcionan ambos, awkutiliza la parte de búsqueda para decidir si la línea actual refleja el patrón y luego realiza las acciones en función de las coincidencias.

En su forma más simple, puedes usar awklike catpara imprimir todas las líneas de un archivo de texto en la pantalla.

Crea un favorite_food.txtarchivo que enumere las comidas favoritas de un grupo de amigos:

echo "carrot sandy
wasabi luke
sandwich brian
salad ryan
spaghetti jessica" > favorite_food.txt

Ahora use el awkcomando para imprimir el archivo en la pantalla:

awk '{print}' favorite_food.txt

Verás el archivo impreso en la pantalla:

Outputcarrot sandy
wasabi luke
sandwich brian
salad ryan
spaghetti jessica

Esto no es muy útil. Probemos awklas funciones de filtrado de búsqueda buscando el texto “arena” en el archivo:

awk '/sand/' favorite_food.txt

Outputcarrot sandy
sandwich brian

Como puedes ver, awkahora solo imprime las líneas que tienen los caracteres “sand” en ellas.

Usando expresiones regulares, puedes seleccionar partes específicas del texto. Para mostrar solo la línea que empieza con las letras “sand”, usa la expresión regular ^sand:

awk '/^sand/' favorite_food.txt

Esta vez, solo se muestra una línea:

Outputsandwich brian

De igual forma, puede usar la sección de acción para especificar qué información desea imprimir. Por ejemplo, para imprimir solo la primera columna, use el siguiente comando:

awk '/^sand/ {print $1;}' favorite_food.txt

Outputsandwich

Puede referenciar cada columna (delimitada por espacios) mediante variables asociadas a su número de columna. Por ejemplo, la primera columna es $1, la segunda es $2, y puede referenciar toda la línea con $0.

Variables internas y formato expandido

El awkcomando utiliza algunas variables internas para asignar ciertas piezas de información mientras procesa un archivo.

Las variables internas que awkutiliza son:

  • NOMBRE DE ARCHIVO : Hace referencia al archivo de entrada actual.
  • FNR : Referencia el número del registro actual en relación con el archivo de entrada actual. Por ejemplo, si tiene dos archivos de entrada, esto le indicaría el número de registro de cada archivo en lugar del total.
  • FS : El separador de campo actual que se utiliza para identificar cada campo de un registro. Por defecto, se establece en espacios.
  • NF : El número de campos en el registro actual.
  • NR : El número del registro actual.
  • OFS : El separador de campo para los datos de salida. Por defecto, se establece en espacios.
  • ORS : El separador de registros para los datos de salida. Por defecto, es un carácter de nueva línea.
  • RS : El separador de registros utilizado para distinguir registros separados en el archivo de entrada. Por defecto, es un carácter de nueva línea.

Puede cambiar los valores de estas variables a voluntad para adaptarlas a las necesidades de sus archivos. Normalmente, esto se hace durante la fase de inicialización del procesamiento.

Esto nos lleva a otro concepto importante. La awksintaxis es un poco más compleja que la que has usado hasta ahora. También hay bloques opcionales BEGINque ENDpueden contener comandos para ejecutarse antes y después del procesamiento del archivo, respectivamente.

Esto hace que nuestra sintaxis expandida se vea más o menos así:

awk 'BEGIN { action; }
/search/ { action; }
END { action; }' input_file

Las palabras clave BEGINy ENDson conjuntos específicos de condiciones, al igual que los parámetros de búsqueda. Coinciden antes y después de procesar el documento.

Esto significa que puedes cambiar algunas de las variables internas de la BEGINsección. Por ejemplo, el /etc/passwdarchivo se delimita con dos puntos ( :) en lugar de espacios.

Para imprimir la primera columna de este archivo, ejecute el siguiente comando:

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

Outputroot
daemon
bin
sys
sync
games
man
. . .

Puede usar los bloques BEGINy ENDpara imprimir información sobre los campos que está imprimiendo. Use el siguiente comando para transformar los datos del archivo en una tabla, con tabulaciones bien espaciadas \t:

awk 'BEGIN { FS=":"; print "User\t\tUID\t\tGID\t\tHome\t\tShell\n--------------"; }
{print $1,"\t\t",$3,"\t\t",$4,"\t\t",$6,"\t\t",$7;}
END { print "---------\nFile Complete" }' /etc/passwd

Verás este resultado:

OutputUser		UID		GID		Home		Shell
--------------
root 		 0 		 0 		 /root 		 /bin/bash
daemon 		 1 		 1 		 /usr/sbin 		 /bin/sh
bin 		 2 		 2 		 /bin 		 /bin/sh
sys 		 3 		 3 		 /dev 		 /bin/sh
sync 		 4 		 65534 		 /bin 		 /bin/sync
. . .
---------
File Complete

Como puedes ver, puedes formatear las cosas bastante bien aprovechando algunas de awklas características de .

Cada sección expandida es opcional. De hecho, la sección de acción principal es opcional si se define otra sección. Por ejemplo, se pueden hacer cosas como esta:

awk 'BEGIN { print "We can use awk like the echo command"; }'

Y verás este resultado:

OutputWe can use awk like the echo command

Ahora veamos cómo buscar texto dentro de los campos de salida.

Búsqueda de campos y expresiones compuestas

En uno de los ejemplos anteriores, imprimiste la línea del favorite_food.txtarchivo que comenzaba con “sand”. Esto fue fácil porque buscabas el comienzo de toda la línea.

¿Qué sucedería si quisieras averiguar si un patrón de búsqueda coincide al principio de un campo ?

Cree una nueva versión del favorite_food.txtarchivo que agregue un número de artículo delante de la comida de cada persona:

echo "1 carrot sandy
2 wasabi luke
3 sandwich brian
4 salad ryan
5 spaghetti jessica" > favorite_food.txt

Si desea encontrar todos los alimentos de este archivo que comienzan con “sa”, puede comenzar probando algo como esto:

awk '/sa/' favorite_food.txt

Esto muestra todas las líneas que contienen “sa”:

Output1 carrot sandy
2 wasabi luke
3 sandwich brian
4 salad ryan

Aquí, se busca cualquier instancia de “sa” en la palabra. Esto termina incluyendo palabras como “wasabi”, que tiene el patrón en el medio, o “sandy”, que no está en la columna deseada. En este caso, solo se buscan palabras que empiecen por “sa” en la segunda columna.

Puedes indicar awkque solo coincida con el comienzo de la segunda columna usando este comando:

awk '$2 ~ /^sa/' favorite_food.txt

Como puedes ver, esto nos permite buscar una coincidencia solo al comienzo de la segunda columna.

La field_num ~parte especifica que awksólo se debe prestar atención a la segunda columna.

Output3 sandwich brian
4 salad ryan

Puedes buscar fácilmente elementos que no coincidan incluyendo el carácter “!” antes de la tilde (~). Este comando devolverá todas las líneas que no tengan un alimento que empiece por “sa”:

awk '$2 !~ /^sa/' favorite_food.txt

Output1 carrot sandy
2 wasabi luke
5 spaghetti jessica

Si más adelante decide que solo le interesan las líneas que no comienzan con “sa” y el número de elemento es menor que 5, puede usar una expresión compuesta como esta:

awk '$2 !~ /^sa/ && $1 < 5' favorite_food.txt

Esto introduce algunos conceptos nuevos. El primero es la posibilidad de añadir requisitos adicionales para que la línea coincida mediante el &&operador. Con este operador, se puede combinar cualquier número de condiciones para que la línea coincida. En este caso, se utiliza este operador para añadir una comprobación de que el valor de la primera columna sea menor que 5.

Verás este resultado:

Output1 carrot sandy
2 wasabi luke

Puedes usarlo awkpara procesar archivos, pero también puedes trabajar con la salida de otros programas.

Procesamiento de la salida de otros programas

Puedes usar el awkcomando para analizar la salida de otros programas en lugar de especificar un nombre de archivo. Por ejemplo, puedes usar awkpara analizar la dirección IPv4 del ipcomando.

El ip acomando muestra la dirección IP, la dirección de difusión y otra información sobre todas las interfaces de red de su equipo. Para mostrar la información de la interfaz llamada eth0, utilice este comando:

ip a s eth0 

Verás los siguientes resultados:

Output2571: eth0@if2572: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:0b brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.11/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

Puedes usarlo awkpara apuntar a la inetlínea y luego imprimir solo la dirección IP:

ip a s eth0 | awk -F '[\/ ]+' '/inet / {print $3}'

La -Fbandera indica awkque se debe delimitar con barras o espacios usando la expresión regular [\/ ]+. Esto divide la línea inet 172.17.0.11/16en campos separados. La dirección IP se encuentra en el tercer campo porque los espacios al principio de la línea también cuentan como un campo, ya que se delimitó con espacios además de barras. Tenga en cuenta que, awken este caso, los espacios consecutivos se tratan como un solo espacio.

La salida muestra la dirección IP:

Output172.17.0.11

Encontrarás muchos lugares donde puedes usar awkpara buscar o analizar la salida de otros comandos.

Conclusión

A estas alturas, deberías tener una comprensión básica de cómo usar el awkcomando para manipular, formatear e imprimir selectivamente archivos y secuencias de texto. Sin embargo, Awk es un tema mucho más amplio y, en realidad, es un lenguaje de programación completo con asignación de variables, estructuras de control, funciones integradas y más. Puedes usarlo en tus propios scripts para formatear texto de forma fiable.

Para obtener más información sobre awk, puede leer el libro gratuito de dominio público de sus creadores que brinda muchos más detalles.

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Post