GNU/Linux >> Tutoriales Linux >  >> Linux

Mejora tus habilidades de awk con dos sencillos tutoriales

Awk es una de las herramientas más antiguas en la caja de herramientas del usuario de Unix y Linux. Creado en la década de 1970 por Alfred Aho, Peter Weinberger y Brian Kernighan (las A, W y K del nombre de la herramienta), awk se creó para el procesamiento complejo de flujos de texto. Es una herramienta complementaria de sed, el editor de secuencias, que está diseñado para el procesamiento de archivos de texto línea por línea. Awk permite programas estructurados más complejos y es un lenguaje de programación completo.

Este artículo explicará cómo usar awk para tareas más estructuradas y complejas, incluida una aplicación simple de combinación de correspondencia.

Estructura del programa Awk

Un script awk se compone de bloques funcionales rodeados de {} (corchetes). Hay dos bloques de funciones especiales, BEGIN y FIN , que se ejecutan antes de procesar la primera línea del flujo de entrada y después de procesar la última línea. En el medio, los bloques tienen el formato:

pattern { action statements }

Cada bloque se ejecuta cuando la línea en el búfer de entrada coincide con el patrón. Si no se incluye ningún patrón, el bloque de funciones se ejecuta en cada línea del flujo de entrada.

Además, la siguiente sintaxis se puede usar para definir funciones en awk que se pueden llamar desde cualquier bloque:

function name(parameter list) { statements }

Esta combinación de bloques y funciones de coincidencia de patrones permite al desarrollador estructurar programas awk para su reutilización y legibilidad.

Cómo procesa awk los flujos de texto

Awk lee el texto de su archivo de entrada o transmite una línea a la vez y usa un separador de campo para analizarlo en varios campos. En terminología awk, el búfer actual es un registro . Hay una serie de variables especiales que afectan la forma en que awk lee y procesa un archivo:

  • FS (separador de campo):por defecto, este es cualquier espacio en blanco (espacios o tabulaciones)
  • RS (separador de registro):De forma predeterminada, una nueva línea (\n )
  • NF (número de campos):cuando awk analiza una línea, esta variable se establece en el número de campos que se han analizado
  • $0: El registro actual
  • $1, $2, $3, etc.: El primer, segundo, tercer campo, etc. del registro actual
  • NR (número de registros):el número de registros que el script awk ha analizado hasta ahora

Hay muchas otras variables que afectan el comportamiento de awk, pero esto es suficiente para empezar.

Awk one-liners

Para una herramienta tan poderosa, es interesante que la mayor parte del uso de awk sean frases sencillas. Quizás el programa awk más común imprime los campos seleccionados desde una línea de entrada de un archivo CSV, un archivo de registro, etc. Por ejemplo, el siguiente renglón imprime una lista de nombres de usuario de /etc/passwd :

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

Como se mencionó anteriormente, $1 es el primer campo en el registro actual. La -F La opción establece la variable FS en el carácter : .

El separador de campo también se puede establecer en un bloque de funciones BEGIN:

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

En el siguiente ejemplo, cada usuario cuyo shell no sea /sbin/nologin se puede imprimir precediendo al bloque con una coincidencia de patrón:

awk 'BEGIN { FS=":" } ! /\/sbin\/nologin/ {print $1 }' /etc/passwd

Awk avanzado:Combinar correspondencia

Ahora que tiene algunos de los conceptos básicos, intente profundizar en awk con un ejemplo más estructurado:crear una combinación de correspondencia.

Una combinación de correspondencia utiliza dos archivos, uno (llamado en este ejemplo email_template.txt ) que contiene una plantilla para un correo electrónico que desea enviar:

From: Program committee <[email protected]>
To: {firstname} {lastname} <{email}>
Subject: Your presentation proposal

Dear {firstname},

Thank you for your presentation proposal:
  {title}

We are pleased to inform you that your proposal has been successful! We
will contact you shortly with further information about the event
schedule.

Thank you,
The Program Committee

Y el otro es un archivo CSV (llamado proposals.csv ) con las personas a las que desea enviar el correo electrónico:

firstname,lastname,email,title
Harry,Potter,[email protected],"Defeating your nemesis in 3 easy steps"
Jack,Reacher,[email protected],"Hand-to-hand combat for beginners"
Mickey,Mouse,[email protected],"Surviving public speaking with a squeaky voice"
Santa,Claus,[email protected],"Efficient list-making"

Desea leer el archivo CSV, reemplazar los campos relevantes en el primer archivo (saltando la primera línea), luego escribir el resultado en un archivo llamado acceptanceN.txt , incrementando N por cada línea que analices.

Escriba el programa awk en un archivo llamado mail_merge.awk . Las declaraciones están separadas por ; en scripts awk. La primera tarea es establecer la variable separadora de campo y un par de otras variables que necesita el script. También debe leer y descartar la primera línea en el CSV, o se creará un archivo que comenzará con Estimado nombre . Para hacer esto, use la función especial getline y restablecer el contador de registros a 0 después de leerlo.

BEGIN {
  FS=",";
  template="email_template.txt";
  output="acceptance";
  getline;
  NR=0;
}

La función principal es muy sencilla:para cada línea procesada, se establece una variable para los distintos campos:firstname , apellido , correo electrónico y título . El archivo de plantilla se lee línea por línea y la función sub se utiliza para sustituir cualquier ocurrencia de las secuencias de caracteres especiales con el valor de la variable relevante. Luego, la línea, con las sustituciones realizadas, se envía al archivo de salida.

Dado que está tratando con el archivo de plantilla y un archivo de salida diferente para cada línea, debe limpiar y cerrar los identificadores de archivo para estos archivos antes de procesar el siguiente registro.

{
        # Read relevant fields from input file
        firstname=$1;
        lastname=$2;
        email=$3;
        title=$4;

        # Set output filename
        outfile=(output NR ".txt");

        # Read a line from template, replace special fields, and
        # print result to output file
        while ( (getline ln < template) > 0 )
        {
                sub(/{firstname}/,firstname,ln);
                sub(/{lastname}/,lastname,ln);
                sub(/{email}/,email,ln);
                sub(/{title}/,title,ln);
                print(ln) > outfile;
        }

        # Close template and output file in advance of next record
        close(outfile);
        close(template);
}

¡Ya terminaste! Ejecute el script en la línea de comando con:

awk -f mail_merge.awk proposals.csv

o

awk -f mail_merge.awk < proposals.csv

y encontrará archivos de texto generados en el directorio actual.

Awk avanzado:recuento de frecuencia de palabras

Una de las características más poderosas de awk es la matriz asociativa. En la mayoría de los lenguajes de programación, las entradas de la matriz generalmente se indexan mediante un número, pero en awk, las matrices se referencian mediante una cadena clave. Puede almacenar una entrada del archivo proposals.txt de la sección anterior. Por ejemplo, en una sola matriz asociativa, como esta:

        proposer["firstname"]=$1;
        proposer["lastname"]=$2;
        proposer["email"]=$3;
        proposer["title"]=$4;

Esto hace que el procesamiento de texto sea muy fácil. Un programa simple que utiliza este concepto es la idea de un contador de frecuencia de palabras. Puede analizar un archivo, dividir palabras (ignorando la puntuación) en cada línea, incrementar el contador para cada palabra en la línea y luego generar las 20 palabras principales que aparecen en el texto.

Primero, en un archivo llamado wordcount.awk , establezca el separador de campo en una expresión regular que incluya espacios en blanco y puntuación:

BEGIN {
        # ignore 1 or more consecutive occurrences of the characters
        # in the character group below
        FS="[ .,:;()<>{}@!\"'\t]+";
}

A continuación, la función de bucle principal iterará sobre cada campo, ignorando los campos vacíos (lo que sucede si hay puntuación al final de una línea), e incrementará el recuento de palabras para las palabras en la línea.

{
        for (i = 1; i <= NF; i++) {
                if ($i != "") {
                        words[$i]++;
                }
        }
}

Finalmente, después de procesar el texto, use la función END para imprimir el contenido de la matriz, luego use la capacidad de awk para canalizar la salida a un comando de shell para hacer una ordenación numérica e imprimir las 20 palabras más frecuentes:

END {
        sort_head = "sort -k2 -nr | head -n 20";
        for (word in words) {
                printf "%s\t%d\n", word, words[word] | sort_head;
        }
        close (sort_head);
}

Ejecutar este script en un borrador anterior de este artículo produjo este resultado:

[[email protected]]$ awk -f wordcount.awk < awk_article.txt 
the     79
awk     41
a       39
and     33
of      32
in      27
to      26
is      25
line    23
for     23
will    22
file    21
we      16
We      15
with    12
which   12
by      12
this    11
output  11
function        11

¿Qué sigue?

Más recursos de Linux

  • Hoja de trucos de los comandos de Linux
  • Hoja de trucos de comandos avanzados de Linux
  • Curso en línea gratuito:Descripción general técnica de RHEL
  • Hoja de trucos de red de Linux
  • Hoja de trucos de SELinux
  • Hoja de trucos de los comandos comunes de Linux
  • ¿Qué son los contenedores de Linux?
  • Nuestros últimos artículos sobre Linux

Si desea obtener más información sobre la programación awk, le recomiendo encarecidamente el libro Sed and awk por Dale Dougherty y Arnold Robbins.

Una de las claves para progresar en la programación awk es dominar las "expresiones regulares extendidas". Awk ofrece varias adiciones poderosas a la sintaxis de expresiones regulares sed con las que quizás ya esté familiarizado.

Otro gran recurso para aprender awk es la guía del usuario de GNU awk. Tiene una referencia completa para la biblioteca de funciones integrada de awk, así como muchos ejemplos de scripts de awk simples y complejos.


Linux
  1. Asegure sus contenedores con SELinux

  2. Escanee su seguridad Linux con Lynis

  3. 13 ejercicios para mejorar tus habilidades con Linux

  4. 10 tutoriales para mejorar tus habilidades de línea de comandos

  5. Linux:¿cómo sincronizar dos carpetas con herramientas de línea de comandos?

Dale sabor a tu escritorio Linux con Cinnamon

Comando AWK en Linux con ejemplos

Guía fácil para monitorear sus sistemas con Checkmk

Pon a prueba tus habilidades BASH jugando juegos de línea de comandos

Manejar el salto de línea con los comandos Fold y FMT en la terminal de Linux

10 tutoriales de Vim para impulsar sus habilidades de editor