awkEmpezando con awk


Observaciones

El nombre AWK proviene de las últimas iniciales de sus creadores Alfred V. Aho, Peter J. Weinberger, y
Brian W. Kernighan.

Recursos

Versiones

Nombre Versión inicial Versión Fecha de lanzamiento
POSIX awk 1992 IEEE Std 1003.1, Edición 2013 2013-04-19
Un Awk verdadero o nawk o BWK awk 198X - 2012-12-20
GNU awk o gawk 1986 4.1.3 2015-05-19

AWK por ejemplos

AWK es un lenguaje de manipulación de cadenas, utilizado en gran medida en sistemas UNIX. La idea detrás de AWK fue crear un lenguaje versátil para usar cuando se trabaja en archivos, que no era demasiado complejo de entender.

AWK tiene otras variantes, pero el concepto principal es el mismo, solo que con características adicionales. Estas otras variantes son NAWK y GAWK. GAWK contiene todas las características de ambos, mientras que NAWK está un paso por encima de AWK, si lo desea.

La forma más sencilla de pensar en AWK es considerar que tiene 2 partes principales. El patrón, y la acción.

Probablemente el ejemplo más básico de AWK: (Ver también: Hola mundo)

BEGIN {print "START"}
      {print        }
END   {print "STOP" }
 

Aquí, las palabras clave BEGIN y END son el patrón, mientras que la acción está dentro de {}. Este ejemplo sería inútil, pero solo se necesitarían cambios menores para convertir esto en una función útil.

BEGIN {print "File\tAuthor"}
      {print $8, "\t", $3}
END {print " - DONE - "}
 

Aquí, \t representa un carácter de tabulador, y se usa para igualar los límites de la línea de salida. $ 8 y $ 3 son similares al uso que se ve en los Shell Scripts , pero en lugar de usar los argumentos 3 y 8, utiliza la tercera y la octava columna de la línea de entrada.

Entonces, este ejemplo imprimirá: Autor del archivo en la línea superior, mientras que la segunda línea tiene que ver con las rutas del archivo. $ 8 es el nombre del archivo, $ 3 es el propietario (Al mirar la ruta del directorio, esto será más claro). Finalmente, la línea de fondo se imprimirá, como era de esperar - HECHO -

El crédito para el ejemplo anterior va a http://www.grymoire.com/Unix/Awk.html

Archivo de referencia

coins.txt de Greg Goebel:

gold     1    1986  USA                 American Eagle
gold     1    1908  Austria-Hungary     Franz Josef 100 Korona
silver  10    1981  USA                 ingot
gold     1    1984  Switzerland         ingot
gold     1    1979  RSA                 Krugerrand
gold     0.5  1981  RSA                 Krugerrand
gold     0.1  1986  PRC                 Panda
silver   1    1986  USA                 Liberty dollar
gold     0.25 1986  USA                 Liberty 5-dollar piece
silver   0.5  1986  USA                 Liberty 50-cent piece
silver   1    1987  USA                 Constitution dollar
gold     0.25 1987  USA                 Constitution 5-dollar piece
gold     1    1988  Canada              Maple Leaf
 

Teoria minima

Awk general de una sola línea:

awk <awk program> <file>
 

o:

<shell-command> | awk <awk program> 
 

<shell-command> y <file> se tratan como entrada awk .

<awk program> es un código que sigue a esta plantilla (comillas simples, no dobles):

'BEGIN   {<init actions>};
 <cond1> {<program actions>};
 <cond2> {<program actions>};
 ...
 END  {<final actions>}'
 

dónde:

  • <condX> condición <condX> es a menudo una expresión regular /re/ , que debe coincidir con las líneas de entrada awk;
  • <* actions> son secuencias de sentencias , similares a los comandos de shell, equipadas con construcciones tipo C.

`` se procesa de acuerdo con las siguientes reglas:
  1. BEGIN ... y END ... son opcionales y se ejecutan antes o después de procesar las líneas de entrada awk.
  2. Para cada línea en la entrada awk, si la condición <condN> es completa, entonces se ejecuta el bloque <program actions> relacionado.
  3. {<program actions>} defecto es {print $0} .

Las condiciones se pueden combinar con operadores lógicos estándar:

    /gold/ || /USA/ && !/1986/
 

donde && tiene precedencia sobre || ;

La declaración print . print item1 item2 imprime artículos en STDOUT.
Los elementos pueden ser variables ( X , $0 ), cadenas ("hola") o números.
item1, item2 con el valor de la variable OFS ;
item1 item2 son justapoxed ! Use item1 " " item2 para espacios o printf para más características.

Las variables no necesitan $ , es decir: print myVar;
Las siguientes variables especiales están incorporadas en awk:

  • FS : actúa como separador de campo para dividir las líneas de entrada awk en los campos. Puedo ser un solo carácter, FS="c" ; una cadena nula, FS="" (entonces cada carácter individual se convierte en un campo separado); una expresión regular sin barras, FS="re" ; FS=" " significa corridas de espacios y tabulaciones y es el valor predeterminado.
  • NF : el número de campos para leer;
  • $1 , $2 , ...: 1er campo, 2do campo. etc. de la línea de entrada actual,
  • $0 : línea de entrada actual;
  • NR : número de línea de put actual.
  • OFS : cadena para clasificar los campos cuando se imprimen.
  • ORS : separador de registro de salida, por defecto una nueva línea.
  • RS : Separador de línea de entrada (registro). Por defecto a nueva línea. Establecer como FS .
  • IGNORECASE : afecta a FS y RS cuando son expresiones regulares;

Ejemplos

Filtra las líneas por expresiones regulares de gold y cuéntalas:

# awk 'BEGIN {print "Coins"} /gold/{i++; print $0}  END {print i " lines out of " NR}' coins.txt
Coins
gold     1    1986  USA                 American Eagle      
gold     1    1908  Austria-Hungary     Franz Josef 100 Korona 
gold     1    1984  Switzerland         ingot 
gold     1    1979  RSA                 Krugerrand 
gold     0.5  1981  RSA                 Krugerrand 
gold     0.1  1986  PRC                 Panda                       
gold     0.25 1986  USA                 Liberty 5-dollar piece
gold     0.25 1987  USA                 Constitution 5-dollar piece
gold     1    1988  Canada              Maple Leaf
9 lines out of 13
 

print $0 y acción de print $0 predeterminadas basadas en la variable awk interna NR :

# awk 'BEGIN {print "First 3 coins"} NR<4' coins.txt
First 3 coins                                                  
gold     1    1986  USA                 American Eagle         
gold     1    1908  Austria-Hungary     Franz Josef 100 Korona 
silver  10    1981  USA                 ingot
 
Formato con estilo C `printf`:
# awk '{printf ("%s \t %3.2f\n", $1, $2)}' coins.txt
gold     1.00                                      
gold     1.00                                      
silver   10.00                                     
gold     1.00                                      
gold     1.00                                      
gold     0.50                                      
gold     0.10                                      
silver   1.00                                      
gold     0.25                                      
silver   0.50                                      
silver   1.00                                      
gold     0.25                                      
gold     1.00
 

Ejemplos de condiciones

awk 'NR % 6'            # prints all lines except those divisible by 6
awk 'NR > 5'            # prints from line 6 onwards (like tail -n +6, or sed '1,5d')
awk '$2 == "foo"'       # prints lines where the second field is "foo"
awk '$2 ~ /re/'         # prints lines where the 2nd field mateches the regex /re/
awk 'NF >= 6'           # prints lines with 6 or more fields
awk '/foo/ && !/bar/'   # prints lines that match /foo/ but not /bar/
awk '/foo/ || /bar/'    # prints lines that match /foo/ or /bar/ (like grep -e 'foo' -e 'bar')
awk '/foo/,/bar/'       # prints from line matching /foo/ to line matching /bar/, inclusive
awk 'NF'                # prints only nonempty lines (or: removes empty lines, where NF==0)
awk 'NF--'              # removes last field and prints the line
 

Al agregar una acción {...} se puede imprimir un campo específico, en lugar de toda la línea, por ejemplo:

awk '$2 ~ /re/{print $3 " " $4}'
 

imprime el tercer y cuarto campo de líneas donde el segundo campo mateches el regex / re /.

Algunas funciones de cadena

Función substr() :

# awk '{print substr($3,3) " " substr($4,1,3)}' 
86 USA                                            
08 Aus                                            
81 USA                                            
84 Swi                                            
79 RSA                                            
81 RSA                                            
86 PRC                                            
86 USA                                            
86 USA                                            
86 USA                                            
87 USA                                            
87 USA                                            
88 Can                                            
 

match(s, r [, arr]) devuelve la posición en s donde la expresión regular r se produce y establece los valores de RSTART y RLENGTH . Si se proporciona el argumento arr , devuelve la matriz arr donde los elementos se configuran para la subexpresión entre paréntesis coincidentes. Las coincidencias del elemento 0 'de arr se establecen en la coincidencia de expresiones regulares completa. También las expresiones arr[n, "start"] y arr[n, "length"] proporcionan la posición inicial y la longitud de cada subcadena correspondiente.

Más funciones de cadena:

sub(/regexp/, "newstring"[, target])
gsub(/regexp/, "newstring"[, target])
toupper("string")
tolower("string")
 

Declaraciones

Una declaración simple es a menudo cualquiera de los siguientes:

variable = expression 
print [ expression-list ] 
printf format [ , expression-list ] 
next # skip remaining patterns on this input line
exit # skip the rest of the input
 

Si stat1 y stat2 son declaraciones, las siguientes también son declaraciones:

{stat}

{stat1;  stat2}

{stat1 
stat2}

if ( conditional ) statement [ else statement ]
 

Los siguientes estándares de tipo C son construcciones son declaraciones:

if ( conditional ) statement [ else statement ]
while ( conditional ) statement
for ( expression ; conditional ; expression ) statement
break    # usual C meaning 
continue # usual C meaning 
 

Un bucle de estilo C para imprimir el elemento de descripción de longitud variable, comenzando con el campo 4:

# awk '{out=""; for(i=4;i<=NF;i++){out=out" "$i}; print out}' coins.txt
USA American Eagle                    
Austria-Hungary Franz Josef 100 Korona
USA ingot                             
Switzerland ingot                     
RSA Krugerrand                        
RSA Krugerrand                        
PRC Panda                             
USA Liberty dollar                    
USA Liberty 5-dollar piece            
USA Liberty 50-cent piece             
USA Constitution dollar               
USA Constitution 5-dollar piece       
Canada Maple Leaf
 

Tenga en cuenta que i se inicializa a 0.

Si las condiciones y los cálculos se aplican a los campos nuneric:

# awk '/gold/ {if($3<1980) print $0 "$" 425*$2}' coins.txt    
gold     1    1908  Austria-Hungary     Franz Josef 100 Korona      $425
gold     1    1979  RSA                 Krugerrand                  $425   
 

Script ejecutable AWK

#!/usr/bin/gawk -f
# This is a comment
(pattern) {action}
...
 

Pasando variables de shell

# var="hello"
# awk -v x="$var" 'BEGIN {print x}'
hello
 

Hola Mundo

El ejemplo de Hello World es tan simple como:

awk 'BEGIN {print "Hello world"}'
 

El programa awk más básico consiste en un valor verdadero (generalmente 1 ) y hace que awk haga eco de su entrada:

$ date | awk '1'
Mon Jul 25 11:12:05 CEST 2016
 

Dado que "hola mundo" también es un verdadero valor, también podría decir:

$ date | awk '"hello world"'
Mon Jul 25 11:12:05 CEST 2016
 

Sin embargo, tu intención se vuelve mucho más clara si escribes

$ date | awk '{print}'
Mon Jul 25 11:12:05 CEST 2016
 

en lugar.

Cómo ejecutar programas AWK

Si el programa es corto, puede incluirlo en el comando que ejecuta awk:

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

En este ejemplo, al usar el interruptor de línea de comando -F: recomendamos a awk usar: como delimitador de campos de entrada. Es igual como

awk 'BEGIN{FS=":"}{print $1,$2}' file
 

Alternativamente, podemos guardar todo el código awk en un archivo awk y llamar a este programa awk así:

awk -f 'program.awk' input-file1 input-file2 ...
 

program.awk puede ser cualquier programa multilínea, es decir:

# file print_fields.awk
BEGIN {print "this is a header"; FS=":"}
{print $1, $2}
END {print "that was it"}
 

Y luego ejecutarlo con:

awk -f print_fields.awk /etc/passwd   #-f advises awk which program file to load
 

O más generalmente:

awk -f program-file input-file1 input-file2 ...
 

La ventaja de tener el programa en un archivo separado es que puede escribir el programa con la identificación correcta para que tenga sentido, puede incluir comentarios con #, etc.