Cómo usar el comando awk en Linux

Contenidos

En Linux, awk es un dínamo de manipulación de texto de línea de comandos, así como un poderoso lenguaje de secuencias de comandos. Aquí hay una introducción a algunas de sus características más interesantes.

RELACIONADO: 10 comandos básicos de Linux para principiantes

Cómo awk consiguió su nombre

los awk El comando fue nombrado usando las iniciales de las tres personas que escribieron la versión original en 1977: Alfred Aho, Peter Weinberger, y Brian Kernighan. Estos tres hombres eran del legendario AT&T Laboratorios Bell Panteón Unix. Con las contribuciones de muchos otros desde entonces, awk ha seguido evolucionando.

Es un lenguaje de secuencias de comandos completo, así como un conjunto de herramientas de manipulación de texto completo para la línea de comandos. Si este post le abre el apetito, puede mira cada detalle sobre awk y su funcionalidad.

Reglas, patrones y acciones

awk trabaja en programas que contienen reglas compuestas por patrones y acciones. La acción se ejecuta en el texto que coincide con el patrón. Los patrones se encierran entre llaves ({}). Juntos, un patrón y una acción forman una regla. La totalidad awk El programa está entre comillas simples (').

Echemos un vistazo al tipo más simple de awk programa. No tiene patrón, por lo que coincide con todas las líneas de texto introducidas en él. Esto significa que la acción se ejecuta en cada línea. Bien úselo en la salida de los who mando.

Aquí está la salida estándar de who:

who

Tal vez no necesitemos toda esa información, sino más bien, solo queremos ver los nombres en las cuentas. Podemos canalizar la salida desde who dentro awky posteriormente decir awk para imprimir solo el primer campo.

Por defecto, awk considera que un campo es una cadena de caracteres rodeada por espacios en blanco, el comienzo de una línea o el final de una línea. Los campos se identifican con un signo de dólar ($) y un número. Entonces, $1 representa el primer campo, que usaremos con el print acción para imprimir el primer campo.

Escribimos lo siguiente:

who | awk '{print $1}'

awk imprime el primer campo y descarta el resto de la línea.

Podemos imprimir tantos campos como queramos. Si agregamos una coma como separador, awk imprime un espacio entre cada campo.

Escribimos lo siguiente para imprimir además la hora en que la persona inició sesión (campo cuatro):

who | awk '{print $1,$4}'

Hay un par de identificadores de campo especiales. Estos representan la línea completa de texto y el último campo en la línea de texto:

  • $ 0: Representa la línea completa de texto.
  • $ 1: Representa el primer campo.
  • $ 2: Representa el segundo campo.
  • $ 7: Representa el séptimo campo.
  • $ 45: Representa el campo 45.
  • $ NF: Significa «número de campos» y representa el último campo.

Escribiremos lo siguiente para que aparezca un pequeño archivo de texto que contiene una breve cita atribuida a Dennis Ritchie:

cat dennis_ritchie.txt

Queremos awk para imprimir el primer, segundo y último campo de la cotización. Tenga en cuenta que, aún cuando está envuelto en la ventana de la terminal, es solo una línea de texto.

Escribimos el siguiente comando:

awk '{print $1,$2,$NF}' dennis_ritchie.txt

No conocemos esa «simplicidad». es el campo número 18 en la línea de texto, y no nos importa. Lo que sí sabemos es que es el último campo y podemos utilizar $NF para obtener su valor. El período se considera simplemente otro carácter en el cuerpo del campo.

Agregar separadores de campo de salida

Además puedes decir awk para imprimir un carácter particular entre campos en lugar del carácter de espacio predeterminado. La salida predeterminada del date el comando es un poco peculiar debido a que el tiempo se coloca justo en el medio. A pesar de esto, podemos escribir lo siguiente y utilizar awk para extraer los campos que queremos:

date
date | awk '{print $2,$3,$6}'

Usaremos el OFS (separador de campo de salida) variable para colocar un separador entre el mes, el día y el año. Tenga en cuenta que a continuación incluimos el comando entre comillas simples ('), no llaves ({}):

date | awk 'OFS="https://www.systempeaker.com/" {print$2,$3,$6}'
date | awk 'OFS="-" {print$2,$3,$6}'

Las reglas BEGIN y END

A BEGIN La regla se ejecuta una vez antes de que comience el procesamiento de texto. En realidad, se ejecuta antes awk inclusive lee cualquier texto. Un END La regla se ejecuta después de que se haya completado todo el procesamiento. Puedes tener varios BEGIN y END reglas, y se ejecutarán en orden.

Para nuestro ejemplo de BEGIN regla, imprimiremos la cita completa de la dennis_ritchie.txt archivo que usamos previamente con un título encima.

Para hacerlo, escribimos este comando:

awk 'BEGIN {print "Dennis Ritchie"} {print $0}' dennis_ritchie.txt

Nota la BEGIN La regla tiene su propio conjunto de acciones encerradas dentro de su propio conjunto de llaves ({}).

Podemos utilizar esta misma técnica con el comando que usamos previamente para canalizar la salida de who dentro awk. Para hacerlo, escribimos lo siguiente:

who | awk 'BEGIN {print "Active Sessions"} {print $1,$4}'

Separadores de campo de entrada

Si deseas awk para trabajar con texto que no utiliza espacios en blanco para separar campos, debe indicarle qué carácter utiliza el texto como separador de campo. A modo de ejemplo, el /etc/passwd el archivo utiliza dos puntos (:) para separar campos.

Usaremos ese archivo y el -F (cadena de separación) opción para decir awk utilizar los dos puntos:) como separador. Escribimos lo siguiente para contar awk para imprimir el nombre de la cuenta de usuario y la carpeta de inicio:

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

La salida contiene el nombre de la cuenta de usuario (o el nombre de la aplicación o demonio) y la carpeta de inicio (o la ubicación de la aplicación).

Adición de patrones

Si lo único que nos interesa son las cuentas de usuario habituales, podemos incluir un patrón con nuestra acción de impresión para filtrar todas las demás entradas. Debido a que ID de usuario Si los números son iguales o superiores a 1.000, podemos basar nuestro filtro en esa información.

Escribimos lo siguiente para ejecutar nuestra acción de impresión solo cuando el tercer campo ($3) contiene un valor de 1000 o más:

awk -F: '$3 >= 1000 {print $1,$6}' /etc/passwd

El patrón debe preceder inmediatamente a la acción con la que está relacionado.

Podemos utilizar el BEGIN regla para proporcionar un título a nuestro pequeño reporte. Escribimos lo siguiente, usando el (n) notación para insertar un carácter de nueva línea en la cadena del título:

awk -F: 'BEGIN {print "User Accountsn-------------"} $3 >= 1000 {print $1,$6}' /etc/passwd

Los patrones son completos expresiones regulares, y son una de las glorias de awk.

Digamos que queremos ver los identificadores únicos universales (UUID) de los sistemas de archivos montados. Si buscamos a través del /etc/fstab archivo para apariciones de la cadena «UUID», debería devolvernos esa información.

Usamos el patrón de búsqueda “/ UUID /” en nuestro comando:

awk '/UUID/ {print $0}' /etc/fstab

Encuentra todas las apariciones de “UUID” e imprime esas líneas. En realidad, hubiéramos obtenido el mismo resultado sin el print acción debido a que la acción predeterminada imprime toda la línea de texto. A pesar de esto, para mayor claridad, a menudo es útil ser explícito. Cuando revise un script o su archivo histórico, se alegrará de haber dejado pistas para usted.

La primera línea que se encontró fue una línea de comentario y, aún cuando la cadena «UUID» está en el medio, awk aún lo encontré. Podemos modificar la expresión regular y decir awk para procesar solo las líneas que comienzan con «UUID». Para hacerlo, escribimos lo siguiente que incluye el token de inicio de línea (^):

awk '/^UUID/ {print $0}' /etc/fstab

¡Eso es mejor! Ahora, solo vemos instrucciones de montaje genuinas. Para refinar aún más la salida, escribimos lo siguiente y restringimos la visualización al primer campo:

awk '/^UUID/ {print $1}' /etc/fstab

Si tuviéramos varios sistemas de archivos montados en esta máquina, obtendríamos una tabla ordenada de sus UUID.

Funciones integradas

awk tiene muchas funciones que puede llamar y usar en sus propios programas, tanto desde la línea de comandos como en scripts. Si investiga un poco, lo encontrará muy fructífero.

Para demostrar la técnica general para llamar a una función, veremos algunas numéricas. A modo de ejemplo, lo siguiente imprime la raíz cuadrada de 625:

awk 'BEGIN { print sqrt(625)}'

Este comando imprime el arcotangente de 0 (cero) y -1 (que resulta ser la constante matemática, pi):

awk 'BEGIN {print atan2(0, -1)}'

En el siguiente comando, modificamos el resultado de la atan2() función antes de imprimirlo:

awk 'BEGIN {print atan2(0, -1)*100}'

Las funciones pueden aceptar expresiones como parámetros. A modo de ejemplo, aquí hay una forma complicada de pedir la raíz cuadrada de 25:

awk 'BEGIN { print sqrt((2+3)*5)}'

guiones awk

Si su línea de comando se complica o desarrolla una rutina que sabe que querrá utilizar nuevamente, puede transferir su awk comando en un script.

En nuestro script de ejemplo, haremos todo lo siguiente:

  • Dígale al shell qué ejecutable utilizar para ejecutar el script.
  • Preparar awk utilizar el FS variable de separación de campo para leer el texto de entrada con campos separados por dos puntos (:).
  • Usar el OFS separador de campo de salida para contar awk utilizar dos puntos:) para separar campos en la salida.
  • Establezca un contador en 0 (cero).
  • Establezca el segundo campo de cada línea de texto en un valor en blanco (siempre es una «x», por lo que no es necesario que la veamos).
  • Imprima la línea con el segundo campo modificado.
  • Incrementa el contador.
  • Imprime el valor del contador.

Nuestro guión se muestra a continuación.

Ejemplo de un script awk en un editor.

los BEGIN regla lleva a cabo los pasos preparatorios, mientras que el END La regla muestra el valor del contador. La regla del medio (que no tiene nombre ni patrón, por lo que coincide con todas las líneas) modifica el segundo campo, imprime la línea e incrementa el contador.

La primera línea del script le dice al shell qué ejecutable utilizar (awk, en nuestro ejemplo) para ejecutar el script. Además pasa el -f (nombre de archivo) opción para awk, que le informa que el texto que va a procesar vendrá de un archivo. Pasaremos el nombre del archivo al script cuando lo ejecutemos.

Hemos incluido el siguiente script como texto para que pueda cortar y pegar:

#!/usr/bin/awk -f

BEGIN {
  # set the input and output field separators
  FS=":"
  OFS=":"
  # zero the accounts counter
  accounts=0
}
{
  # set field 2 to nothing
  $2=""
  # print the entire line
  print $0
  # count another account
  accounts++
}
END {
  # print the results
  print accounts " accounts.n"
}

Guarda esto en un archivo llamado omit.awk. Para hacer que el script sea ejecutablemi, escribimos lo siguiente usando chmod:

chmod +x omit.awk

Ahora, lo ejecutaremos y pasaremos el /etc/passwd archivo a la secuencia de comandos. Este es el archivo awk procesará por nosotros, usando las reglas dentro del script:

./omit.awk /etc/passwd

El archivo se procesa y se muestra cada línea, como se muestra a continuación.

Se eliminaron las entradas «x» en el segundo campo, pero tenga en cuenta que los separadores de campo aún están presentes. Las líneas se cuentan y el total se da en la parte inferior de la salida.

awk no significa incómodo

awk no significa incómodo; es sinónimo de elegancia. Se ha descrito como un filtro de procesamiento y un redactor de informes. Más exactamente, son ambos o, mejor dicho, una herramienta que puede usar para ambas tareas. En solo unas pocas líneas, awk logra lo que necesita una codificación extensa en un lenguaje tradicional.

Ese poder es aprovechado por el concepto simple de reglas que contienen patrones, que seleccionan el texto a procesar y acciones que definen el procesamiento.

setTimeout(function(){
!function(f,b,e,v,n,t,s)
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version=’2.0′;
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t,s) } (window, document,’script’,
‘https://connect.facebook.net/en_US/fbevents.js’);
fbq(‘init’, ‘335401813750447’);
fbq(‘track’, ‘PageView’);
},3000);

Suscribite a nuestro Newsletter

No te enviaremos correo SPAM. Lo odiamos tanto como tú.