Copyright © 2005-2019 LinuxTotal.com.mx
Se concede permiso para copiar, distribuir y/o modificar este documento siempre y cuando se cite al autor y la fuente de linuxtotal.com.mx y según los términos de la GNU Free Documentation License, Versión 1.2 o cualquiera posterior publicada por la Free Software Foundation.
awk
o la versión GNU gawk
es más que un simple comando de procesamiento de patrones, es todo un lenguaje de análisis semántico. Su dominio es como aprender todo un lenguaje de programación, pero en esta ocasión veremos unos ejemplos de su potencia en unos casos sencillos de análisis de patrones de cadenas, espero te sirvan de base para que puedas aprender aun más sobre esta interesante herramienta.
Una línea típica de /etc/passwd es como la siguiente:
luis:x:504:504:Luis Hernandez:/home/luis:/bin/bash
Bien, supongamos que deseamos un listado de todos los usuarios normales (personas) del sistema, pero solo necesitamos su nombre de usuario, su nombre o real y su shell por defecto, es decir, si vemos la línea anterior, la separación entre campos es ":" asi que para nuestro reporte queremos el campo 1,5 y 7. Pero además, este reporte será parte de una tabla HTML, asi que sería bueno si puderian incluirse de una vez las etquietas "<tr> y "<td> necesarias de una vez. Es decir, el resultado deseado es el siguiente:
<tr><td>luis<td><td>Luis Hernandez</td><td>/bin/bash</td></tr>
El primer paso es determinar los usuarios normales del sistema, podríamos usar un grep "home" /etc/passw | gawk ...
, pero podría haber usuarios que tengan su HOME en otra ubicación, además se trata de usar solo awk
, asi que lo primero que entenderemos es que los campos obtenidos del resultado de un comando awk
, se numeran por $1, $2, etc. y el delimitador de campos se indica mediante la variable "FS".
#> gawk '{print $3}' FS=":" /etc/passwd 0 1 2 ... 81 86 500 501 502 503 504
Aunque no muy útil todavía, podemos ver como seleccionamos el caracter separador FS=":", que viene de 'Field Separator', y tenemos indicada una acción '{print $3}', que significa imprime el campo 3. Aunque realmente no lo queremos imprimir, lo queremos evaluar, y si deseamos imprimir el $1, $5 y $7 que se mencionarion previamente, asi que agregamos una expresión de evaluación antes de la acción:
#> awk '$3 >= 500 {print $1 $5 $7 }' FS=":" /etc/passwd sergonSergio Gonzalez/bin/bash valeriaValeria Perez/bin/bash fernandaFernanda Lozano/bin/sh alejandraAlejandra Lopez/bin/nologin luisLuis Hernandez/bin/bash
Mucho mejor, agregamos '$3 >= 500' previo a la acción (que es imprimir lo que deseamos), ya que como se sabe en la mayoría de distros modernas, los usuarios normales del sistema se numeran del 500 en adelante (más sobre administración de usuarios). Nótese que los campos en el resultado salen pegados, es necesario agregar entre comillas " ", ya sea un espacio o lo que se desee, en este caso etiquetas de tablas de HTML y además ordenaremos "sort" los registros obtenidos:
#> awk '$3 >= 500 {print "<tr><td>"$1"</td><td>"$5"</td><td>"$7"</td></tr>" | "sort" }' FS=":" /etc/passwd <tr><td>alejandra</td><td>Alejandra Lopez</td><td>/bin/nologin</td></tr> <tr><td>fernanda</td><td>Fernanda Lozano</td><td>/bin/sh</td></tr> <tr><td>luis</td><td>Luis Hernandez</td><td>/bin/bash</td></tr> <tr><td>sergon</td><td>Sergio Gonzalez</td><td>/bin/bash</td></tr> <tr><td>valeria</td><td>Valeria Perez</td><td>/bin/bash</td></tr>
Ahora veamos como crear una lista similar a la anterior pero especificando un par de líneas de títulos al inicio:
#> awk 'BEGIN { print "Usuario UID Shell\n------- --- -----" } $3 >= 500 { print $1, $3, $7 | "sort -r"}' FS=":" /etc/passwd Usuario UID Shell ------- --- ----- valeria 501 /bin/bash sergon 500 /bin/bash luis 504 /bin/bash fernanda 502 /bin/sh alejandra 503 /bin/nologin
Iniciamos con la sentencia BEGIN (que tiene varios usos, checa el manual) que en este caso nos permite indicar lo que se imprimirá una sola vez, en este caso los títulos, un retorno '\n' y guiones para separar los títulos, después viene de nuevo la evaluación ya conocida y ahora al indicar la impresión de los campos 'print $1, $3, $7', los separé por comas, que automáticamente añade un espacio, y solo para aumentar el ejemplo, el ordenamiento es ahora al revés 'sort -r'.
Pero podemos ver en la salida, que los registros no se acomodan bien con respecto a los títulos, con dos o tres campos tal vez resulte fácil añadir espacios o tabuladores '\t' para hacer el acomodo, pero en varios campos será realmente frustrante lograrlo. Mejor usamos 'printf':
#> awk 'BEGIN { print "Usuario UID Shell\n------------ ---- ----------" } $3 >= 500 \ { printf "%12s %4d %10s\n", $1, $3, $7 | "sort -r"}' FS=":" /etc/passwd Usuario UID Shell ------------ ---- ---------- valeria 501 /bin/bash sergon 500 /bin/bash luis 504 /bin/bash fernanda 502 /bin/sh alejandra 503 /bin/nologin
Sigo usando 'print' para los títulos, pero ahora uso 'printf' que me permite formatear la salida, la sintaxis es 'printf "formato", $1, $2'. Cada formato comienza con '%' después el número de posiciones seguido del tipo de campo 's' para string, 'd' para enteros, etc. '%12s' 12 posiciones de tipo cadena. (checar el manual para el resto de formatos de printf), termino el formato con un salto de línea '\n'. Pero como se puede apreciar por defecto las cadenas se justifican a la derecha y en este caso las deseamos a la izquierda, esto se arregla agregando un '-' guión en el indicador de formato de la siguiente manera '%-12s', el resultado correcto sería el siguiente:
# awk 'BEGIN { print "Usuario UID Shell\n------------ ---- ----------" } $3 >= 500 \ { printf "%-12s %4d %-10s\n", $1, $3, $7 | "sort -r"}' FS=":" /etc/passwd Usuario UID Shell ------------ ---- ---------- valeria 501 /bin/bash sergon 500 /bin/bash luis 504 /bin/bash fernanda 502 /bin/sh alejandra 503 /bin/nologin
Hay ocasiones en que no se tiene exactamente la posición de los campos a extraer, asi que usaremos otra técnica basada en el número total de campos encontrados. En este caso, necesitamos la variable "NF" (Number of Fields) que representa el total de campos encontrados. Y usaremos como caracter separador FS el espacio, es decir FS=" ", pero dado que el espacio es el separador por defecto no es necesario indicarlo.
Como ejemplo, veamos la salida del comando uptime
:
$> uptime 19:32:15 up 2:28, 1 user, load average: 1.75, 1.54, 1.54
Y deseamos crear un pequeño script que de como resultado el siguiente:
$> ./carga carga actual del sistema: 1min=1.75, 5min=1.54, 15min=1.54
Como se puede observar, se necesitan los tres últimos campos, aparentemente los campos $8, $9 y $10. Pero el problema esta en que conforme pasa el tiempo, el comando uptime
mostrará de hecho más campos, ya que el que en este momento es el $3 '2:28' después de unos días puede quedar asi '3 days 3:50', asi que al usar NF nos dará el total de campos, veamos:
$> uptime | gawk '{print NF}' 10 $> uptime | gawk '{print $NF}' 1.33
Entendiendo lo anterior, es fácil de deducir entonces que los campos requeridos son entonces NF-2, NF-1, NF es decir, los tres últimos, y no importará cuantos campos haya en el resultado.
$> uptime | gawk '{print $(NF - 2), $(NF - 1), $NF}' 0.72, 0.54, 0.47
El script quedaría entonces así:
#!/bin/bash echo "Carga actual del sistema: " uptime | gawk '{print "1min:"$(NF - 2), "5min:"$(NF - 1), "15min:"$NF}'
Si encuentras útil la información que proveé LinuxTotal, considera realizar un donativo que estimule a seguir proporcionando contenido de calidad y utilidad. Gracias.
Dona a través de paypal::
O a través de bitcoins:
....
awk o la versión GNU gawk es más que un simple comando de procesamiento de patrones, es todo un lenguaje de análisis semántico....
Hay ocasiones que cuando busco un archivo dentro del listado de un directorio con varios archivos, usando ls, deseo ver solamente ....
Hay ocasiones en que se te ofrece hacer cálculos matemáticos o aritméticos y no estás en el ambiente gráfico para abrir una c....
De acuerdo a la definición en wikipedia un rootkit es una herramienta, o un grupo de ellas que tiene como finalidad esconderse a ....
Linux es un sistema multiusuario, por lo tanto, la tarea de añadir, modificar, eliminar y en general administrar usuarios se conv....
Una de las dificultades con una base de datos MySQL grande y activa es la de realizar respaldos limpios sin tener que desconectar ....
Ya no es nada raro que un centro de cómputo o en un site se encuentren varios sistemas Linux actuando como servidores de archivos....
La más simple definición de un proceso podría ser que es una instancia de un programa en ejecución (corriendo). A los procesos....
En Linux existen tres formas de controlar y mostrar la marca del tiempo en archvios y directorios. Asi es, cuando creas o editas u....