Busca patrones y los procesa. Es practicamente un lenguaje de programación.
Archivo base para ejemplo (Empleado -- Precio/hora -- Horas trabajadas – Cómo las cobra):
$ cat lista
Juan Gomez 6 10 banco
Clara Fuentes 7 12 banco
Antonio Cano 6 13 metálico
José Bueno 7 0 banco
Matías Crespo 5 8 metálico
Isabel Ruiz 7 0 metálico
María Monzón 9 16 metálico
Imprimir la segunda columna (Apellidos):
$ awk ' { print $2 } ' lista
Imprimir la última columna:
$ awk ' { print $NF } ' lista
Imprimir la linea 3:
$ awk ' NR == 3 ' lista
Imprimir todo menos la primera columna:
$ awk ' { $1 = "" ; print } ' lista
Imprimir las columnas tabuladas:
$ awk ' { print $1 “\t” $2 “\t” $3 “\t” $4 } ' lista
Imprimir las lineas que tengan menos de 22 caracteres:
$ awk 'length($0) < 22' lista
Calcular el sueldo de los empleados que han trabajado:
$ awk ' $4 > 0 { print $1,$2, $3*$4} ' lista
Personas que no han trabajado:
$ awk ' $3 == 0 { print $1}' lista
Buscar una entrada concreta:
$ awk '/Fuentes/ { print $0 }' lista
Buscar los que cobran en metálico e impimir la 2ª columna:
$ awk ' /'metálico'/ {print$2}' lista
Buscar dos entradas en una misma linea separándolas con punto y coma (;):
$ awk '/Fuentes/ { print $0 }; /Cano/ { print$0 } ' lista
Imprimir lineas que tengan alguno de los campos o los dos:
$ awk '/Bueno/ || /Cano/' lista
Imprimir lineas que tengan los dos campos:
$ awk '/Bueno/ && /7/' lista
Imprimir las lineas que no tengan el cammpo:
$ awk '! /metálico/' lista
Buscar las entradas en las que el primer campo empiece por “J”, imprimir el 2º campo y, entre parentesis el último:
$ awk '$1 ~ /^J/ {print$2, "("$NF")"}' lista
Lo mismo con if:
$ awk ' { if ($1 ~ /^J/) print$2, “(“$NF”)” }' lista
Añadir 5 horas al 4º campo y comprobar como quedan con la modificación:
$ awk '{ $4 = ($4+5); print $0 }' lista
Añadir un nuevo campo ($6) con el producto del 3 y el 4:
$ awk '{ $6 = ($3*$4); print $0 }' lista
print permite colocar texto:
$ awk ' { print "El sueldo de ",$2," es de ",$3*$4," euros."} ' lista
Mostar las veces que aparece "banco":
awk 'BEGIN { print "Veces que aparece banco" }
> /banco/ { ++banco }
> END { print "banco aparece " banco " veces." }' lista
**Variables internas:**
Mostrar el número de campos de cada linea (NF):
$ awk ' { print NF } ' lista
Mostrar el número de lineas (NR):
$ awk ' { print NR } ' lista
Mostrar todas las lineas completas ($0):
$ awk ' { print $0 } ' lista
Mostrar las lineas que tengan al menos un campo
$ awk 'NF > 0' lista
Lo mismo con if:
$ awk '{ if (NF > 0) print }' lista
Dar formato a la salida de datos:
$ awk ' $4 > 0 { printf "%-8s .... %8.1f euros\n",$2,($3*$4) } ' lista
$4 > 0 (Que imprima los que la 4ª columna no sea cero.)
%-8s (Que imprima una cadena (s) justificada a la izquierda (-) en un campo de 8 caracteres de ancho.)
%8.1f (Que imprima un numero real (f), en un campo de ocho caracteres de ancho, con un decimal(.))
Imprimir cadena, justificada a la izquierda y en campos de 10 y 5 caracteres:
$ awk '{ printf "%-10s %-10s %-5s %-5s %-5s\n", $1, $2, $3, $4, $5 }' lista
Parecido con más florituras (todo en una sola linea)
$ awk 'BEGIN {print "nombre\tapellido\tprecio\thoras\tpago"; print "------\t--------\t------\t-----\t----"}; {print $1"\t"$2"\t"$3"\t"$4"\t"$5 }' lista
Lo mismo más legible:
$ awk 'BEGIN {print "nombre\tapellido\tprecio\thoras\tpago"
> print "------\t--------\t------\t-----\t----"}
> {print $1"\t"$2"\t"$3"\t"$4"\t"$5 }' lista
BEGIN y END son patrones especiales usados para suministrar al script awk qué hacer antes de empezar a procesar y después de haber procesado los registros de la entrada.:
$ awk 'BEGIN {print “Cuantas veces aparece la palabra banco” }
> /banco/ { ++i }
> END {print “banco aparece “i” veces.”}' lista
Los patrones pueden combinarse mediante los operadores lógicos AND (&&), OR(||) y NOT(!).
Imprimir los nombres de los empleados que ganan mas de 6.50 euros a la hora y que han trabajado mas de 14:
$ awk ' $3>=6.50 && $4>=14 { print $1,$2 } ' lista
Patrones
buscar las lineas que contienen la cadena "banco" en el 5º campo:
$ awk ' $5 ~ /banco/ ' lista
Buscar las lineas que no contengan la cadena "banco" en el 5º campo:
$ awk ' $5 !~ /banco/ ' lista
Mostrar los que el 4º campo no empiece por 0 o 1:
$ awk ' $4 ~ /^[^01]/' lista
La salida también puede pasarse a un filtro para ordenarse:
$ awk ' { print $2 | "sort" } ' lista
Mostrar la linea cuyo 2º campo termina en “iz”:
$ awk '$2 ~ /iz$/' lista
Mismo concepto sin especificar si la primera letra es mayúscula o minúscula y sin conocer la segunda:
$ awk '$1 ~ /^[Cc]./' lista
Mismo concepto incluyendo las que empiezan por “R”:
$ awk '$2 ~ /^[Cc].|^[R]/' lista
“tolower” convierte el campo especificado a minúsculas:
$ awk 'tolower($1) ~ /^m/' lista
Para mandar cada linea a un archivo con el nombre del 2er campo:
$ awk ' { print > $2 } ' lista
Mandar el primer campo a un archivo y el segundo a otro:
$ awk '{ print $1 > "nombres"; print $2 > "apellidos" }' lista
Lo mismo pero mandándolo ordenado:
$ awk '{ print $1 | "sort > nombres"; print $2 | "sort > apellidos" }' lista
Indicando caracter separador (un espacio y que imprima el 2º campo):
$ awk -F " " ' { print $2 } ' lista
Lo mismo usando BEGIN:
$ awk 'BEGIN { FS = " " } ; { print $2 }' lista
El siguiente programa muestra como puede usarse awk para validación de datos.
$ cat validar
$3 < 6.5 { print $1,$2 " ===> precio por hora bajo", "("$3")" }
$3 > 8 { print $1,$2 " ===> precio por hora alto", "("$3")" }
$5 == "banco" { print $1,$2 " ===> Cobra por banco" }
$5 == "metálico" { print $1,$2 " ===> Cobra en metálico" }
Se ejecuta con:
$ awk -f validar lista
Aunque también podríamos añadir que lo ordenara por orden alfabetico del segundo campo (-k2) separado del primero por un espacio(-t” “):
$ awk -f validar lista | sort -t” “ -k2
Otros ejemplos:
$ awk '/d.[0-9]/{print $4}' /proc/partitions (listar todas las particiones)
$ cat 1.txt | awk '{print$1”\t”$2}' (tabulando la salida)
$ cat 1.txt | awk '!/#/{print $0}' > 2.txt (Imprime todo menos las lineas comentadas y lo manda a un archivo)
$ cat 1.txt | awk 'BEGIN { FS="\n"; RS="" } { print $1 }' > lista.txt (Manda a un archivo las primeras lineas precedidas de una en blanco)
$ who | awk '{print $1}' (Mostrar todos los usuarios registrados)
$ awk '$1~/^DocumentRoot/{print $2}' /etc/apache2/sites-available/default (conocer la carpeta del servidor)
$ awk 'BEGIN { for (i = 1; i <= 7; i++) print int(101 * rand()) }' (Escribir 7 números aleatorios del 0 al 100)
$ awk ' { print "\"" $0 "\""} ' lista (Entrecomillar cada una de la lineas del archivo)
Creación de scripts con awk:
1.-
Imprimir el simple "Hola mundo cruel"
#!/usr/bin/awk -f
BEGIN { print "Hola mundo cruel" }
Lo mismo pero incluido en un script de bash:
#!/bin/bash
awk 'BEGIN { print "Hola mundo cruel" }'
2.-
Mandar el segundo campo de listado.txt a un archivo y el sexto a otro:
#! /usr/bin/awk -f
awk '{ print$2 > "lista_nombres"
print$6 > "lista_telefonos" }' listado.txt
3.-
Pasar el comando date... a variable [getline dia_actual], cerrar el comando [close] e imprimirlo en pantalla:
#!/usr/bin/awk -f
BEGIN {
"date +%d-%m-%Y" | getline dia_actual
close("date +%d-%m-%Y")
print "Hoy estamos a " dia_actual
}
En bash:
awk 'BEGIN {
"date +%d-%m-%Y" | getline dia_actual
close("date +%d-%m-%Y")
print "Hoy estamos a " dia_actual
}'
4.-
Usar variables dentro de awk
variable="primera linea\nsegunda linea"
awk 'BEGIN {print "'"$variable"'"}'
primera linea
segunda linea