uso de awk.pdf
TRANSCRIPT
Uso básico de AWK
Qué es awk
AWK es una herramienta de procesamiento de patrones en líneas de texto. Su utilización estándar es la
de filtrar ficheros o salida de comandos de UNIX, tratando las líneas para, por ejemplo, mostrar una
determinada información sobre las mismas.
Por ejemplo:
Mostrar sólo los nombres y los tamaños de los ficheros: # ls -l | awk '{ print $8 ":" $5 }'
Mostrar sólo los nombres y tamaños de ficheros .txt: # ls -l | awk '$8 ~ /\.txt/ { print $8 ":" $5 }'
Imprimir las líneas que tengan más de 4 campos/columnas: # awk 'NF > 4 {print}' fichero
Formato de uso
El uso básico de AWK es:
awk [condicion] { comandos }
Donde:
[condicion] representa una condición de matcheo de líneas o parámetros.
comandos : una serie de comandos a ejecutar:
$0 → Mostrar la línea completa
$1-$N → Mostrar los campos (columnas) de la línea especificados.
FS → Field Separator (Espacio o TAB por defecto)
NF → Número de campos (fields) en la línea actual
NR → Número de líneas (records) en el stream/fichero a procesar.
OFS → Output Field Separator (” ”).
ORS → Output Record Separator (“\n”).
RS → Input Record Separator (“\n”).
BEGIN → Define sentencias a ejecutar antes de empezar el procesado.
END → Define sentencias a ejecutar tras acabar el procesado.
length → Longitud de la línea en proceso.
FILENAME → Nombre del fichero en procesamiento.
ARGC → Número de parámetros de entrada al programa.
ARGV → Valor de los parámetros pasados al programa.
Las funciones utilizables en las condiciones y comandos son, entre otras:
sromero.org [Uso básico de AWK] http://www.sromero.org/wiki/linux/aplicaciones/us...
1 de 6 26/10/10 14:54
close(fichero_a_reiniciar_desde_cero)
cos(x), sin(x)
index()
int(num)
lenght(string)
substr(str,pos,len)
tolower()
toupper()
system(orden_del_sistema_a_ejecutar)
printf()
Los operadores soportados por awk son los siguientes:
*, /, %, +, -, =, ++, --, +=, -=, *=, /=, %=.
El control de flujo soportado por AWK incluye:
if ( expr ) statement
if ( expr ) statement else statement
while ( expr ) statement
do statement while ( expr )
for ( opt_expr ; opt_expr ; opt_expr ) statement
for ( var in array ) statement
continue, break
(condicion)? a : b → if(condicion) a else b;
Las operaciones de búsqueda son las siguientes:
/cadena/ → Búsqueda de cadena.
/^cadena/ → Búsqueda de cadena al principio de la línea.
/cadena$/ → Búsqueda de cadena al final de la línea.
$N ~ /cadena/ → Búsqueda de cadena en el campo N.
$N !~ /cadena/ → Búsqueda de cadena NO en el campo N.
/(cadena1)|(cadena2)/ → Búsqueda de cadena1 OR cadena2.
/cadena1/,/cadena2>/ → Todas las líneas entre cadena1 y cadena2.
Ejemplos de selección de columnas
Mostrar una determinada columna de información: # ls -l | awk '{ print $5 }' 176869 12 4096 4096
Mostrar varias columnas, así como texto adicional (entre comillas): # ls -l | awk '{ print $8 ":" $5 }' AEMSolaris7.pdf:176869 fich1:12
sromero.org [Uso básico de AWK] http://www.sromero.org/wiki/linux/aplicaciones/us...
2 de 6 26/10/10 14:54
Desktop:4096 docs:4096
Imprimir campos en otro orden: # awk '{ print $2, $1 }' fichero
Imprimir último campo de cada línea: # awk '{ print $NF }' fichero
Imprimir los campos en orden inverso: # awk '{ for (i = NF; i > 0; --i) print $i }' fichero
Imprimir última línea: # awk '{line = $0} END {print line}'
Imprimir primeras N líneas: # awk 'NR < 100 {print}'
Mostrar las líneas que contienen valores numéricos mayor o menor que uno dado: # ls -l | awk '$5 > 1000000 { print $8 ":" $5 }'
# ls -l | awk '$5 > 1000000 || $5 < 100 { print $8 ":" $5 }' fich1:12 z88dk-src-1.7.tgz:2558227 (También hay operaciones &&)
Mostrar la línea con el valor numérico más grande en un campo determinado: # awk '$1 > max { max=$1; linea=$0 }; END { print max, linea }' fichero
Mostrar aquellos ficheros cuya longitud es mayor que 10 caracteres: # ls -l | awk 'length($8) > 10 { print NR " " $8 }' 2 AEMSolaris7.pdf 10 function_keys.txt 14 notas_solaris.txt 19 z88dk-src-1.7.tgz (Campo $8 -nombrefichero- > 10 caracteres, y numero de record)
Mostrar líneas con más o menos de N caracteres: # awk 'length > 75' fichero # awk 'length < 75' fichero
Mostrar campos/líneas que cumplan determinadas condiciones entre campos: # awk '$2 > $3 {print $3}' fichero # awk '$1 > $2 {print length($1)}' fichero
Mostrar y el número de campos de un fichero además de la línea: # awk '{ print NF ":" $0 } ' fichero
Mostrar y numerar sólo las líneas no vacías (no en blanco): # awk 'NF { $0=++a " :" $0 }; { print }' Imprimir las líneas que tengan más de N campos: # awk 'NF > 5 { print $0 }' fichero
Mostrar el número de línea de cada fichero de una lista iniciando desde cero la cuenta de líneas al empezar cada fichero: # awk '{print FNR "\t:" $0}' *.txt
Mostrar el número de línea de cada fichero de una lista sin resetear la cuenta de líneas al empezar cada nuevo fichero: # awk '{print FNR "\t:" $0}' *.txt
Matcheo/Sustitución de cadenas
sromero.org [Uso básico de AWK] http://www.sromero.org/wiki/linux/aplicaciones/us...
3 de 6 26/10/10 14:54
Mostrar las líneas que contengan una determinada cadena # awk '/cadena/ { print }' fichero
Mostrar las líneas que NO contengan una determinada cadena # awk '! /cadena/ { print }' fichero
# ls -l | awk '/4096/ { print $8 ":" $5 }' Desktop:4096 docs:4096
Mostrar todas las líneas que aparezcan entre 2 cadenas: # awk '/cadena_inicio/, /cadena_fin/' fichero
Comparaciones exactas de cadenas: # awk '$1 == "fred" { print $3 }' fichero
Líneas que contengan cualquier numero en punto flotante: # awk '/[0-9]+\.[0-9]*/ { print }' fichero
Busqueda de cadenas en un campo determinado # awk '$5 ~ /root/ { print $3 }' fichero
# ls -l | awk '$8 ~ /txt/ { print $8 ":" $5 }' apuntes.txt:9342 function_keys.txt:2252 notas_solaris.txt:57081 (Nota, con ~ hemos buscado sólo /txt/ en el campo $8)
Sustituir cadena1 por cadena2: # awk '{ gsub(/cadena1/,"cadena2"); print }' fichero
Sustituir 1 por 2 sólo en las líneas que contengan "cadena3". # awk '/cadena3/ { gsub(/1/, "2") }; { print }' fichero
Sustituir una cadena en las líneas que no contengan "cadena3". # awk '!/cadena3/ { gsub(/1/, "2") }; { print }' fichero
Sustituir una cadena u otra: # awk '{ gsub(/cadena1|cadena2/, "nueva"); print}' fichero
Filtrado / Eliminación de información
Filtrar las líneas en blanco (numero campos ==0): # cat file.txt | awk {' if (NF != 0) print $0 '}
Contar número de líneas donde la columna 3 sea mayor que la 1: # awk '$3 > $1 {print i + "1"; i++}' fichero
Eliminar campo 2 de cada línea: # awk '{$2 = ""; print}' fichero
Eliminar líneas duplicadas aunque sean no consecutivas:lines. # awk '!temp_array[$0]++' fichero
(Se basa en utilizar un array de tipo hash/diccionario temporal donde las líneas que aún no han aparecido valen 0, y las que han aparecido !=0)
Saltar 1000 Líneas de un fichero: # awk '{if ( NR > 1000 ) { print $0 }}' fichero
Saltar líneas < 10 y > 20: # awk '(NR >= 0) && (NR <= 20) { print $0 }'
sromero.org [Uso básico de AWK] http://www.sromero.org/wiki/linux/aplicaciones/us...
4 de 6 26/10/10 14:54
Cálculos de tamaños / longitudes
Imprimir el número de líneas que contienen una cadena: # awk '/cadena/ {nlines = nlines + 1} END {print nlines}' fichero Sumar todos los tamaños de ficheros de un ls -l, o con una condición: # ls -l | awk '{ sum += $5 } END { print sum }' 3660106 # ls -l | awk ' $3 == "sromero" { sum += $5 } END { print sum }' 3660106
Contar número de líneas del fichero: # awk 'END {print NR}' infile
Contar el número de líneas vacías de un fichero: # awk 'BEGIN { x=0 } /^$/ {x=x+1} END { print "Lineas vacias:", x }' fichero NOTA: Expandido para leerlo mejor: BEGIN { x=0 } /^$/ { x=x+1 } END { print "Lineas vacias:", x }
Contar el número de palabras / campos en un fichero: # awk '{ total = total + NF }; END { print total+0 }' fichero
Contar el número total de líneas que contienen una cadena: # awk '/cadena/ { total++ }; END { print total+0 }' fichero
Imprimir con formato: yes | head -10 | awk '{printf("%2.0f", NR)}'
Calcular la suma de todos los campos de cada línea # awk '{suma=0; for (i=1; i<=NF; i++) suma=suma+$i; print suma}' fichero
Calcular la suma y la media de todas las primeras columnas del fichero: # awk '{ suma += $1 } END { print "suma:", s, " media:", s/NR }
Cambio de IFS (Field Separator)
Sacar campos 1 y 3 de /etc/passwd: # awk -F":" '{ print $1 "\t" $3 }' /etc/passwd
Sacar datos de un fichero CSV separado por comas: # awk -F"," '$1=="Nombre" { print $2 }' fichero.csv
Otros
Tabular líneas con 3 espacios: # awk '{ sub(/^/, " "); print }'
Obtener 1 números aleatorio: # awk '{print rand()}'
sromero.org [Uso básico de AWK] http://www.sromero.org/wiki/linux/aplicaciones/us...
5 de 6 26/10/10 14:54
Generar 40 número aleatorio (0-100) sustituyendo la línea por el número: # yes | head -40 | awk '{ print int(101*rand())}'
Generar 40 números aleatorios sólo con awk: # awk 'BEGIN { for (i = 1; i <= 40; i++) print int(101 * rand()) }'
Reemplazar cada campo por su valor absoluto: # awk '{ for (i=1; i<=NF; i=i+1) if ($i<0) $i=-$i print}' fichero
Definición y utilización de funciones propias (sólo nawk): # awk '{for (field=1; field<=NF; ++field) {print EsPositivo($field)}};
function EsPositivo(n) { if (n<0) return 0 else return 1 }' Partir un mbox en ficheros individuales (Ben Okopnik en Linux Gazzette #175). # awk '{if (/^From /) f=sprintf("%%03d",++a);print>>f}' mail_file
<Volver a la sección de GNU/Linux>
linux/aplicaciones/uso_de_awk.txt · Última modificación: 05-06-2010 04:19 por sromero
sromero.org [Uso básico de AWK] http://www.sromero.org/wiki/linux/aplicaciones/us...
6 de 6 26/10/10 14:54