Una guía para principiantes de Gawk

quedarse sin palabras es la implementación GNU de Awk Lenguaje de programación, desarrollado por primera vez para el sistema operativo UNIX en la década de 1970. El lenguaje de programación Awk se especializa en manejar datos de formato en archivos de texto, especialmente datos de texto organizados en columnas.

Usando el lenguaje de programación Awk, puede manipular o extraer datos, generar informes, combinar modelos, realizar cálculos, etc. con gran flexibilidad. Awk le permite realizar tareas algo difíciles con solo una 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 hace referencia 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. En aras de la simplicidad, 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 hacia awk para extraer e imprimir datos, pero awk también puede procesar datos de archivos.

En este artículo usarás awk para analizar datos en un archivo con columnas separadas por espacios. Comencemos mirando los datos de muestra.

Índice

    Data de muestra

    Para los ejemplos de esta guía, usemos la salida del comando ps ux guardado en archivo psux.out. Aquí hay un ejemplo 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.

    Entonces usemos awk para mostrar los datos del archivo de muestra.

    Uso básico

    Un basico awk El programa consta de un patrón seguido de una acción rodeada de llaves. Puede proporcionar un horario para 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) fila por fila, realizando la acción dada para cada fila o registro que coincida con el patrón. Si se omite el patrón, awk realiza la acción en todos los registros. Una acción puede ser tan simple como imprimir datos de fila o tan compleja como un programa completo. Por ejemplo, para imprimir todas las líneas del archivo de muestra, 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 ....

    Aunque este ejemplo no es realmente útil, ilustra la awk uso básico del comando.

    Si usas el comando ps ux en su máquina, puede dirigir su salida directamente a awk, en lugar de proporcionar el nombre del archivo de entrada:

    $ ps ux | awk '{ print }'

    Entonces usemos awk Capacidades de procesamiento de columnas para extraer parte de los datos del archivo de muestra.

    Imprimir campos

    El poder de awk comienza a ser evidente cuando utiliza sus funciones de procesamiento de columnas. awk divide automáticamente cada fila (o registro) en campos. Por defecto, utiliza el espacio carácter para separar cada campo, pero puede cambiar esto proporcionando el parámetro de línea de comando -F seguido del separador deseado.

    Después de la separación, awk asigna a cada campo una variable numerada, comenzando con el carácter $. Por ejemplo, el primer campo es $1, la segunda $2, etc La variable especial $0 contiene toda la grabación antes de dividirla.

    Mediante el uso de 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 fila:

    $ 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 separados por comas. Por ejemplo, para imprimir el nombre del comando y el uso 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, utilice el printf para formatear 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 %sn", $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 plantilla para filtrar los registros.

    Coincidencia de patrones

    Además de manipular campos, awk le permite filtrar los registros en los que realizar acciones con una potente función de coincidencia de patrones. En su uso más básico, proporcione una expresión regular rodeada por una barra inclinada / caracteres para hacer coincidir los registros. Por ejemplo, para filtrar por registros que coincidan, use /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 de proceso que coincidan con 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 usando over, use $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 modelos con operadores. Por ejemplo, para mostrar todos los procesos que coinciden y usan, combine los dos modelos con el && operador para una lógica AND:

    $ 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 fila del encabezado. Puede agregar su propia fila de encabezado usando el BEGIN plantilla para realizar una sola acción antes de procesar los registros:

    $ awk 'BEGIN { printf("%-26s %sn", "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 campo

    Como vimos en el apartado anterior, awk incluye campos numéricos. Esto le permite realizar la manipulación de datos, incluidos los cálculos numéricos. Por ejemplo, considere imprimir el uso de memoria en la columna seis para todos los 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 el uso de memoria en kilobytes, que es difícil de leer. Convirtámoslo a megabytes sumergiendo el valor del campo a 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 los números y agregar el sufijo usando printf para mejorar la legibilidad:

    $ awk '/firefox/ { printf("%s %4.0f MBn", $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, combina esta idea con la BEGIN y END modelos para realizar una manipulación de datos más avanzada. Por ejemplo, calculemos el uso total de memoria para todos los procesos configurando una variable suma en el BEGIN acción, sumando el valor de la columna seis $6 por cada fila que coincida con el suma variable, luego imprímala con el END acción en megas:

    $ awk 'BEGIN { sum=0 } /firefox/ { sum+=$6 } END { printf("Total Firefox memory: %.0f MBn", sum/1024) }' psux.out
    Total Firefox memory: 1747 MB

    ¿Y después?

    gawk es una herramienta poderosa y flexible para procesar datos textuales, especialmente datos organizados en columnas. Este artículo ha proporcionado algunos ejemplos útiles del uso de esta herramienta para extraer y manipular datos, pero gawk puede hacer mucho más. Para más información sobre gawk, consulte las páginas del manual de su distribución de Linux.

    El lenguaje Awk tiene muchos más recursos que los que hemos explorado en esta guía. Para obtener información detallada sobre esto, consulte el sitio web oficial Guía del usuario de GNU Awk.

    Artículos de interés

    Subir