gawk es la implementación GNU del lenguaje de programación Awk, desarrollado por primera vez para el sistema operativo UNIX en la década de 1970. El lenguaje de programación Awk se especializa en el manejo del formato de datos en archivos de texto, particularmente datos de texto organizados en columnas.
Con el lenguaje de programación Awk, puede manipular o extraer datos, generar informes, combinar patrones, realizar cálculos y más, con gran flexibilidad. Awk le permite realizar tareas algo difíciles con una sola línea de código. Lograr los mismos resultados usando lenguajes de programación tradicionales como C o Python requeriría un esfuerzo adicional y muchas líneas de código.
gawk
también se refiere a la utilidad de línea de comandos disponible de forma predeterminada con la mayoría de las distribuciones de Linux. La mayoría de las distribuciones también proporcionan un enlace simbólico para awk
apuntando a gawk
. Para simplificar, de ahora en adelante, nos referiremos a la utilidad solo como awk
.
awk
procesa datos directamente desde la entrada estándar - STDIN. Un patrón común es canalizar la salida de otros programas a awk
para extraer e imprimir datos, pero awk
también puede procesar datos de archivos.
En este artículo, usará awk
para analizar datos de un archivo con columnas separadas por espacios. Comencemos por revisar los datos de muestra.
Datos de ejemplo
Para los ejemplos de esta guía, usemos la salida del comando ps ux
guardado en el archivo psux.out
. Aquí hay una muestra de los datos en el archivo:
$ head psux.out
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
ricardo 1446 0.0 0.2 21644 11536 ? Ss Sep10 0:00 /usr/lib/systemd/systemd --user
ricardo 1448 0.0 0.1 49212 5848 ? S Sep10 0:00 (sd-pam)
ricardo 1459 0.0 0.1 447560 7148 ? Sl Sep10 0:00 /usr/bin/gnome-keyring-daemon --daemonize --login
ricardo 1467 0.0 0.1 369144 6080 tty2 Ssl+ Sep10 0:00 /usr/libexec/gdm-wayland-session /usr/bin/gnome-session
ricardo 1469 0.0 0.1 277692 4112 ? Ss Sep10 0:00 /usr/bin/dbus-broker-launch --scope user
ricardo 1471 0.0 0.1 6836 4408 ? S Sep10 0:00 dbus-broker --log 4 --controller 11 --machine-id 16355057c7274843823dd747f8e2978b --max-bytes 100000000000000 --max-fds 25000000000000 --max-matches 5000000000
ricardo 1474 0.0 0.3 467744 14132 tty2 Sl+ Sep10 0:00 /usr/libexec/gnome-session-binary
ricardo 1531 0.0 0.1 297456 4280 ? Ssl Sep10 0:00 /usr/libexec/gnome-session-ctl --monitor
ricardo 1532 0.0 0.3 1230908 12920 ? S<sl Sep10 0:01 /usr/bin/pulseaudio --daemonize=no
Puede descargar el archivo completo desde aquí, usando este comando:
$ curl -o psux.out https://gitlab.com/-/snippets/2013935/raw\?inline\=false
Si decide utilizar la salida de ps ux
en su sistema, ajuste los valores que se muestran en los ejemplos para que coincidan con sus resultados.
A continuación, usemos awk
para ver los datos del archivo de muestra.
Uso básico
Un awk
básico El programa consta de un patrón seguido de una acción encerrada entre llaves. Puede proporcionar un programa al awk
utilidad en línea encerrándola entre comillas simples, así:
$ awk 'pattern { action }'
awk
procesa los datos de entrada (entrada estándar o archivo) línea por línea, ejecutando la acción dada para cada línea o registro que coincida con el patrón. Si se omite el patrón, awk
ejecuta la acción en todos los registros. Una acción puede ser tan simple como imprimir datos de la línea o tan compleja como un programa completo. Por ejemplo, para imprimir todas las líneas del archivo de ejemplo, use este comando:
$ awk '{ print }' psux.out
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
ricardo 1446 0.0 0.2 21644 11536 ? Ss Sep10 0:00 /usr/lib/systemd/systemd --user
.... OUTPUT TRUNCATED ....
Si bien este ejemplo no es realmente útil, ilustra el awk
utilización básica del comando.
Si estás usando el comando ps ux
en su máquina, puede canalizar su salida directamente a awk
, en lugar de proporcionar el nombre del archivo de entrada:
$ ps ux | awk '{ print }'
A continuación, usemos awk
capacidades de procesamiento de columnas para extraer parte de los datos del archivo de muestra.
Campos de impresión
El poder de awk
comienza a ser evidente cuando utiliza sus funciones de procesamiento de columnas. awk
divide automáticamente cada línea, o registro, en campos. De forma predeterminada, utiliza el espacio carácter para separar cada campo, pero puede cambiar eso proporcionando el parámetro de línea de comando -F
seguido del separador deseado.
Después de dividir, awk
asigna cada campo a una variable numerada, comenzando con el carácter $
. Por ejemplo, el primer campo es $1
, el segundo $2
, y así. La variable especial $0
contiene el registro completo antes de dividirlo.
Al usar las variables de campo, puede extraer datos de la entrada. Por ejemplo, para imprimir solo el nombre del comando del archivo de muestra, use la variable $11
porque el nombre del comando es la undécima columna de cada línea:
$ awk '{ print $11 }' psux.out
COMMAND
/usr/lib/systemd/systemd
(sd-pam)
/usr/bin/gnome-keyring-daemon
.... OUTPUT TRUNCATED ....
También puede imprimir varios campos separándolos con comas. Por ejemplo, para imprimir el nombre del comando y la utilización de la CPU en la columna tres, use este comando:
$ awk '{ print $11, $3 }' psux.out
COMMAND %CPU
/usr/lib/systemd/systemd 0.0
(sd-pam) 0.0
/usr/bin/gnome-keyring-daemon 0.0
.... OUTPUT TRUNCATED ....
Finalmente, use el printf
incorporado función para dar formato a la salida y alinear las columnas. Proporcione un relleno de 40 caracteres a la derecha de las primeras columnas para acomodar nombres de comando más largos:
$ awk '{ printf("%-40s %s\n", $11, $3) }' psux.out
COMMAND %CPU
/usr/lib/systemd/systemd 0.0
(sd-pam) 0.0
/usr/bin/gnome-keyring-daemon 0.0
/usr/libexec/gdm-wayland-session 0.0
.... OUTPUT TRUNCATED ....
Ahora que puede manipular y extraer campos individuales de cada registro, apliquemos la función de patrón para filtrar los registros.
[ También te puede interesar: Manipulación de texto en la línea de comandos con sed ]
Coincidencia de patrones
Además de manipular campos, awk
le permite filtrar en qué registros ejecutar acciones a través de una potente función de coincidencia de patrones. En su uso más básico, proporciona una expresión regular encerrada por una barra inclinada /
caracteres para hacer coincidir los registros. Por ejemplo, para filtrar por registros que coincidan con firefox , usa /firefox/
:
$ awk '/firefox/ { print $11, $3 }' psux.out
/usr/lib64/firefox/firefox 66.2
/usr/lib64/firefox/firefox 8.3
/usr/lib64/firefox/firefox 15.6
/usr/lib64/firefox/firefox 9.0
/usr/lib64/firefox/firefox 31.5
/usr/lib64/firefox/firefox 20.6
/usr/lib64/firefox/firefox 31.0
/usr/lib64/firefox/firefox 0.0
/usr/lib64/firefox/firefox 0.0
/usr/lib64/firefox/firefox 0.0
/usr/lib64/firefox/firefox 0.0
/usr/lib64/firefox/firefox 0.0
/usr/lib64/firefox/firefox 0.0
También puede utilizar campos y una expresión de comparación como criterios de coincidencia de patrones. Por ejemplo, para imprimir datos del proceso que coincidan con el PID 6685, compare el campo $2
, así:
$ awk '$2==6685 { print $11, $3 }' psux.out
/usr/lib64/firefox/firefox 0.0
awk
es lo suficientemente inteligente como para comprender los campos numéricos, lo que le permite usar comparaciones relativas como mayor que o menor que. Por ejemplo, para mostrar todos los procesos que utilizan más del 5 % de CPU , usa $3 > 5
:
$ awk '$3 > 5 { print $11, $3 }' psux.out
/usr/bin/gnome-shell 5.1
/usr/lib64/firefox/firefox 66.2
/usr/lib64/firefox/firefox 8.3
/usr/lib64/firefox/firefox 15.6
/usr/lib64/firefox/firefox 9.0
/usr/lib64/firefox/firefox 31.5
/usr/lib64/firefox/firefox 20.6
/usr/lib64/firefox/firefox 31.0
Puede combinar patrones con operadores. Por ejemplo, para mostrar todos los procesos que coinciden con firefox y usa más del 5 % de la CPU , combine ambos patrones con &&
operador para un AND
lógico :
$ awk '/firefox/ && $3 > 5 { print $11, $3 }' psux.out
/usr/lib64/firefox/firefox 66.2
/usr/lib64/firefox/firefox 8.3
/usr/lib64/firefox/firefox 15.6
/usr/lib64/firefox/firefox 9.0
/usr/lib64/firefox/firefox 31.5
/usr/lib64/firefox/firefox 20.6
/usr/lib64/firefox/firefox 31.0
Finalmente, debido a que está utilizando la coincidencia de patrones, awk
ya no imprime la línea de encabezado. Puede agregar su propia línea de encabezado usando BEGIN
patrón para ejecutar una sola acción antes de procesar cualquier registro:
$ awk 'BEGIN { printf("%-26s %s\n", "Command", "CPU%")} $3 > 10 { print $11, $3 }' psux.out
Command CPU%
/usr/lib64/firefox/firefox 66.2
/usr/lib64/firefox/firefox 15.6
/usr/lib64/firefox/firefox 31.5
/usr/lib64/firefox/firefox 20.6
/usr/lib64/firefox/firefox 31.0
A continuación, manipulemos los datos en campos individuales.
Manipulación de campos
Como discutimos en la sección anterior, awk
entiende los campos numéricos. Esto le permite realizar la manipulación de datos, incluidos los cálculos numéricos. Por ejemplo, considere imprimir la utilización de la memoria en la columna seis para todos los firefox procesos:
$ awk '/firefox/ { print $11, $6 }' psux.out
/usr/lib64/firefox/firefox 301212
/usr/lib64/firefox/firefox 118220
/usr/lib64/firefox/firefox 168468
/usr/lib64/firefox/firefox 101520
/usr/lib64/firefox/firefox 194336
/usr/lib64/firefox/firefox 111864
/usr/lib64/firefox/firefox 163440
/usr/lib64/firefox/firefox 38496
/usr/lib64/firefox/firefox 174636
/usr/lib64/firefox/firefox 37264
/usr/lib64/firefox/firefox 30608
/usr/lib64/firefox/firefox 174636
/usr/lib64/firefox/firefox 174660
El comando ps ux
muestra la utilización de la memoria en Kilobytes, que es difícil de leer. Vamos a convertirlo a Megabytes sumergiendo el valor del campo en 1024:
$ awk '/firefox/ { print $11, $6/1024 }' psux.out
/usr/lib64/firefox/firefox 294.152
/usr/lib64/firefox/firefox 115.449
/usr/lib64/firefox/firefox 164.52
/usr/lib64/firefox/firefox 99.1406
/usr/lib64/firefox/firefox 189.781
/usr/lib64/firefox/firefox 109.242
/usr/lib64/firefox/firefox 159.609
/usr/lib64/firefox/firefox 37.5938
/usr/lib64/firefox/firefox 170.543
/usr/lib64/firefox/firefox 36.3906
/usr/lib64/firefox/firefox 29.8906
/usr/lib64/firefox/firefox 170.543
/usr/lib64/firefox/firefox 170.566
También puede redondear números y agregar el sufijo MB usando printf
para mejorar la legibilidad:
$ awk '/firefox/ { printf("%s %4.0f MB\n", $11, $6/1024) }' psux.out
/usr/lib64/firefox/firefox 294 MB
/usr/lib64/firefox/firefox 115 MB
/usr/lib64/firefox/firefox 165 MB
/usr/lib64/firefox/firefox 99 MB
/usr/lib64/firefox/firefox 190 MB
/usr/lib64/firefox/firefox 109 MB
/usr/lib64/firefox/firefox 160 MB
/usr/lib64/firefox/firefox 38 MB
/usr/lib64/firefox/firefox 171 MB
/usr/lib64/firefox/firefox 36 MB
/usr/lib64/firefox/firefox 30 MB
/usr/lib64/firefox/firefox 171 MB
/usr/lib64/firefox/firefox 171 MB
Finalmente, combine esta idea con BEGIN
y END
patrones para realizar una manipulación de datos más avanzada. Por ejemplo, calculemos la utilización de memoria total para todos los firefox procesos definiendo una variable suma en el BEGIN
acción, sumando el valor de la columna seis $6
por cada línea que coincida con firefox a la suma y luego imprimiéndola con el END
acción en Megabytes:
$ awk 'BEGIN { sum=0 } /firefox/ { sum+=$6 } END { printf("Total Firefox memory: %.0f MB\n", sum/1024) }' psux.out
Total Firefox memory: 1747 MB
[ Descargar ahora:una guía para administradores de sistemas sobre secuencias de comandos Bash. ]
¿Qué sigue?
gawk
es una herramienta poderosa y flexible para procesar datos de texto, particularmente datos organizados en columnas. Este artículo proporcionó algunos ejemplos útiles del uso de esta herramienta para extraer y manipular datos, pero gawk
puede hacer mucho más. Para obtener información adicional sobre gawk
, consulte las páginas del manual en su distribución de Linux.
El lenguaje Awk tiene muchos más recursos que los que exploramos en esta guía. Para obtener información detallada al respecto, consulte la Guía del usuario oficial de GNU Awk.