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
.
awk
Es 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 awk
herramienta de línea de comandos y cómo procesar texto.
Sintaxis básica
El awk
comando está incluido de forma predeterminada en todos los sistemas Linux modernos, por lo que no es necesario instalarlo para comenzar a usarlo.
awk
Es 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 awk
comando 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 awk
comando. 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, awk
realiza la acción que aparece en cada línea.
Si se proporcionan ambos, awk
utiliza 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 awk
like cat
para imprimir todas las líneas de un archivo de texto en la pantalla.
Crea un favorite_food.txt
archivo 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 awk
comando 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 awk
las 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, awk
ahora 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 awk
comando utiliza algunas variables internas para asignar ciertas piezas de información mientras procesa un archivo.
Las variables internas que awk
utiliza 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 awk
sintaxis es un poco más compleja que la que has usado hasta ahora. También hay bloques opcionales BEGIN
que END
pueden 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 BEGIN
y END
son 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 BEGIN
sección. Por ejemplo, el /etc/passwd
archivo 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 BEGIN
y END
para 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 awk
las 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.txt
archivo 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.txt
archivo 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 awk
que 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 awk
só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 awk
para procesar archivos, pero también puedes trabajar con la salida de otros programas.
Procesamiento de la salida de otros programas
Puedes usar el awk
comando para analizar la salida de otros programas en lugar de especificar un nombre de archivo. Por ejemplo, puedes usar awk
para analizar la dirección IPv4 del ip
comando.
El ip a
comando 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 awk
para apuntar a la inet
línea y luego imprimir solo la dirección IP:
ip a s eth0 | awk -F '[\/ ]+' '/inet / {print $3}'
La -F
bandera indica awk
que se debe delimitar con barras o espacios usando la expresión regular [\/ ]+
. Esto divide la línea inet 172.17.0.11/16
en 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, awk
en 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 awk
para 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 awk
comando 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.