Awk es un lenguaje de secuencias de comandos de propósito general diseñado para el procesamiento de texto avanzado. Se utiliza principalmente como una herramienta de informes y análisis.
A diferencia de la mayoría de los otros lenguajes de programación que son de procedimiento, awk está basado en datos, lo que significa que usted define un conjunto de acciones que se realizarán en el texto de entrada. Toma los datos de entrada, los transforma y envía el resultado a la salida estándar.
Este artículo cubre los aspectos esenciales del lenguaje de programación awk. Conocer los conceptos básicos de awk mejorará significativamente su capacidad para manipular archivos de texto en la línea de comandos.
Cómo awk
funciona
Hay varias implementaciones diferentes de awk. Usaremos la implementación GNU de awk, que se llama gawk. En la mayoría de los sistemas Linux, el awk
intérprete es solo un enlace simbólico a gawk
.
registros y campos
Awk puede procesar archivos y flujos de datos textuales. Los datos de entrada se dividen en registros y campos. Awk opera en un registro a la vez hasta que se alcanza el final de la entrada. Los registros están separados por un carácter llamado separador de registros. El separador de registros predeterminado es el carácter de nueva línea, lo que significa que cada línea en los datos de texto es un registro. Se puede establecer un nuevo separador de registros usando la RS
variable.
Los registros consisten en campos que están separados por el separador de campo. De forma predeterminada, los campos están separados por un espacio en blanco, incluidos uno o más caracteres de tabulación, espacio y nueva línea.
Los campos de cada registro se referencian con el signo de dólar ( $
) seguido del número de campo, comenzando con 1. El primer campo se representa con $1
, el segundo con $2
, y así sucesivamente. El último campo también se puede referenciar con la variable especial $NF
. Se puede hacer referencia a todo el registro con $0
.
Aquí hay una representación visual que muestra cómo hacer referencia a registros y campos:
tmpfs 788M 1.8M 786M 1% /run/lock
/dev/sda1 234G 191G 31G 87% /
|-------| |--| |--| |--| |-| |--------|
$1 $2 $3 $4 $5 $6 ($NF) --> fields
|-----------------------------------------|
$0 --> record
programa awk
Para procesar un texto con awk
, escribe un programa que le dice al comando qué hacer. El programa consta de una serie de reglas y funciones definidas por el usuario. Cada regla contiene un patrón y un par de acciones. Las reglas están separadas por nueva línea o punto y coma ( ;
). Por lo general, un programa awk se ve así:
pattern { action }
pattern { action }
...
Cuando awk
procesa datos, si el patrón coincide con el registro, realiza la acción especificada en ese registro. Cuando la regla no tiene patrón, todos los registros (líneas) coinciden.
Una acción awk está encerrada entre llaves ( {}
) y consta de declaraciones. Cada instrucción especifica la operación a realizar. Una acción puede tener más de una declaración separada por nueva línea o punto y coma ( ;
). Si la regla no tiene acción, por defecto imprime todo el registro.
Awk admite diferentes tipos de declaraciones, incluidas expresiones, condicionales, declaraciones de entrada, salida y más. Las declaraciones awk más comunes son:
exit
- Detiene la ejecución de todo el programa y sale.next
- Detiene el procesamiento del registro actual y pasa al siguiente registro en los datos de entrada.print
- Imprimir registros, campos, variables y texto personalizado.printf
- Le da más control sobre el formato de salida, similar a C y bashprintf
.
Al escribir programas awk, todo lo que sigue a la marca hash (#)
y hasta el final de la línea se considera un comentario. Las líneas largas se pueden dividir en varias líneas usando el carácter de continuación, barra invertida ( \
).
Ejecutando programas awk
Un programa awk se puede ejecutar de varias maneras. Si el programa es corto y simple, se puede pasar directamente al awk
intérprete en la línea de comandos:
awk 'program' input-file...
Al ejecutar el programa en la línea de comandos, debe estar entre comillas simples ( ''
), para que el shell no interprete el programa.
Si el programa es grande y complejo, lo mejor es ponerlo en un archivo y usar la -f
opción de pasar el archivo al awk
comando:
awk -f program-file input-file...
En los ejemplos a continuación, usaremos un archivo llamado "teams.txt" que se parece al siguiente:
Bucks Milwaukee 60 22 0.732
Raptors Toronto 58 24 0.707
76ers Philadelphia 51 31 0.622
Celtics Boston 49 33 0.598
Pacers Indiana 48 34 0.585
Patrones extraños
Los patrones en awk controlan si la acción asociada debe ejecutarse o no.
Awk admite diferentes tipos de patrones, incluidos patrones de expresión regular, expresión de relación, rango y expresión especial.
Cuando la regla no tiene patrón, cada registro de entrada coincide. Aquí hay un ejemplo de una regla que contiene solo una acción:
awk '{ print $3 }' teams.txt
El programa imprimirá el tercer campo de cada registro:
60
58
51
49
48
Patrones de expresiones regulares
Una expresión regular o regex es un patrón que coincide con un conjunto de cadenas. Los patrones de expresiones regulares de Awk están encerrados entre barras ( //
):
/regex pattern/ { action }
El ejemplo más básico es una coincidencia de cadena o carácter literal. Por ejemplo, para mostrar el primer campo de cada registro que contiene "0.5", ejecutaría el siguiente comando:
awk '/0.5/ { print $1 }' teams.txt
Celtics
Pacers
El patrón puede ser cualquier tipo de expresión regular extendida. Aquí hay un ejemplo que imprime el primer campo si el registro comienza con dos o más dígitos:
awk '/^[0-9][0-9]/ { print $1 }' teams.txt
76ers
Patrones de expresiones relacionales
Los patrones de expresiones relacionales se utilizan generalmente para hacer coincidir el contenido de un campo o variable específicos.
De forma predeterminada, los patrones de expresiones regulares se comparan con los registros. Para hacer coincidir una expresión regular con un campo, especifique el campo y use el operador de comparación "contener" ( ~
) con el patrón.
Por ejemplo, para imprimir el primer campo de cada registro cuyo segundo campo contenga “ia”, escribiría:
awk '$2 ~ /ia/ { print $1 }' teams.txt
76ers
Pacers
Para hacer coincidir campos que no contienen un patrón dado, use el !~
operador:
awk '$2 !~ /ia/ { print $1 }' teams.txt
Bucks
Raptors
Celtics
Puede comparar cadenas o números para relaciones como mayor que, menor que, igual, etc. El siguiente comando imprime el primer campo de todos los registros cuyo tercer campo es mayor que 50:
awk '$3 > 50 { print $1 }' teams.txt
Bucks
Raptors
76ers
Patrones de rango
Los patrones de rango constan de dos patrones separados por una coma:
pattern1, pattern2
Todos los registros que comienzan con un registro que coincide con el primer patrón hasta que coinciden con un registro que coincide con el segundo patrón.
Aquí hay un ejemplo que imprimirá el primer campo de todos los registros a partir del registro que incluye "Raptors" hasta el registro que incluye "Celtics":
awk '/Raptors/,/Celtics/ { print $1 }' teams.txt
Raptors
76ers
Celtics
Los patrones también pueden ser expresiones de relación. El siguiente comando imprimirá todos los registros a partir de aquel cuyo cuarto campo es igual a 32 hasta aquel cuyo cuarto campo es igual a 33:
awk '$4 == 31, $4 == 33 { print $0 }' teams.txt
76ers Philadelphia 51 31 0.622
Celtics Boston 49 33 0.598
Los patrones de rango no se pueden combinar con otras expresiones de patrón.
Patrones de expresiones especiales
Awk incluye los siguientes patrones especiales:
BEGIN
- Se utiliza para realizar acciones antes de que se procesen los registros.END
- Se utiliza para realizar acciones después de que se procesan los registros.
El BEGIN
patrón generalmente se usa para establecer variables y el END
patrón para procesar datos de los registros, como el cálculo.
El siguiente ejemplo imprimirá "Iniciar procesamiento", luego imprimirá el tercer campo de cada registro y finalmente "Terminar procesamiento":
awk 'BEGIN { print "Start Processing." }; { print $3 }; END { print "End Processing." }' teams.txt
Start Processing
60
58
51
49
48
End Processing.
Si un programa tiene solo un BEGIN
patrón, las acciones se ejecutan y la entrada no se procesa. Si un programa solo tiene un END
patrón, la entrada se procesa antes de realizar las acciones de la regla.
La versión Gnu de awk también incluye dos patrones especiales más BEGINFILE
y ENDFILE
, que le permite realizar acciones al procesar archivos.
Combinando patrones
Awk le permite combinar dos o más patrones utilizando el operador lógico AND ( &&
) y el operador lógico OR ( ||
).
Aquí hay un ejemplo que usa el &&
operador para imprimir el primer campo de aquellos registros cuyo tercer campo es mayor a 50 y el cuarto campo es menor a 30:
awk '$3 > 50 && $4 < 30 { print $1 }' teams.txt
Bucks
Raptors
Variables integradas
Awk tiene una serie de variables integradas que contienen información útil y le permite controlar cómo se procesa el programa. A continuación se muestran algunas de las variables integradas más comunes:
NF
- El número de campos en el registro.NR
- El número del registro actual.FILENAME
- El nombre del archivo de entrada que se procesa actualmente.FS
- Separador de campos.RS
- Separador de registros.OFS
- Separador de campo de salida.ORS
- Separador de registros de salida.
Aquí hay un ejemplo que muestra cómo imprimir el nombre del archivo y el número de líneas (registros):
awk 'END { print "File", FILENAME, "contains", NR, "lines." }' teams.txt
File teams.txt contains 5 lines.
Las variables en AWK se pueden configurar en cualquier línea del programa. Para definir una variable para todo el programa, colóquela en un BEGIN
patrón.
Cambio del separador de campos y registros
El valor predeterminado del separador de campo es cualquier número de espacios o caracteres de tabulación. Se puede cambiar configurando en la FS
variable.
Por ejemplo, para establecer el separador de campo .
, usaría:
awk 'BEGIN { FS = "." } { print $1 }' teams.txt
Bucks Milwaukee 60 22 0
Raptors Toronto 58 24 0
76ers Philadelphia 51 31 0
Celtics Boston 49 33 0
Pacers Indiana 48 34 0
El separador de campo también se puede establecer en más de un carácter:
awk 'BEGIN { FS = ".." } { print $1 }' teams.txt
Al ejecutar awk one-liners en la línea de comandos, también puede usar la -F
opción para cambiar el separador de campo:
awk -F "." '{ print $1 }' teams.txt
De forma predeterminada, el separador de registros es un carácter de nueva línea y se puede cambiar mediante la RS
variable.
Aquí hay un ejemplo que muestra cómo cambiar el separador de registro a .
:
awk 'BEGIN { RS = "." } { print $1 }' teams.txt
Bucks Milwaukee 60 22 0
732
Raptors Toronto 58 24 0
707
76ers Philadelphia 51 31 0
622
Celtics Boston 49 33 0
598
Pacers Indiana 48 34 0
585
Acciones Awk
Las acciones de Awk se encierran entre llaves ( {}
) y se ejecutan cuando el patrón coincide. Una acción puede tener cero o más declaraciones. Las declaraciones múltiples se ejecutan en el orden en que aparecen y deben estar separadas por nueva línea o punto y coma ( ;
).
Hay varios tipos de instrucciones de acción compatibles con awk:
- Expresiones, como asignación de variables, operadores aritméticos, operadores de incremento y decremento.
- Sentencias de control, utilizadas para controlar el flujo del programa (
if
,for
,while
,switch
y más) - Instrucciones de salida, como
print
yprintf
. - Sentencias compuestas, para agrupar otras sentencias.
- Declaraciones de entrada, para controlar el procesamiento de la entrada.
- Instrucciones de eliminación, para eliminar elementos de la matriz.
La print
declaración es probablemente la declaración awk más utilizada. Imprime una salida formateada de texto, registros, campos y variables.
Al imprimir varios elementos, debe separarlos con comas. Aquí hay un ejemplo:
awk '{ print $1, $3, $5 }' teams.txt
Los elementos impresos están separados por espacios simples:
Bucks 60 0.732
Raptors 58 0.707
76ers 51 0.622
Celtics 49 0.598
Pacers 48 0.585
Si no usa comas, no habrá espacio entre los elementos:
awk '{ print $1 $3 $5 }' teams.txt
Los elementos impresos se concatenan:
Bucks600.732
Raptors580.707
76ers510.622
Celtics490.598
Pacers480.585
Cuando print
se usa sin un argumento, el valor predeterminado es print $0
. Se imprime el registro actual.
Para imprimir un texto personalizado, debe citar el texto con caracteres de comillas dobles:
awk '{ print "The first field:", $1}' teams.txt
The first field: Bucks
The first field: Raptors
The first field: 76ers
The first field: Celtics
The first field: Pacers
También puede imprimir caracteres especiales como nueva línea:
awk 'BEGIN { print "First line\nSecond line\nThird line" }'
First line
Second line
Third line
La printf
declaración le da más control sobre el formato de salida. Aquí hay un ejemplo que inserta números de línea:
awk '{ printf "%3d. %s\n", NR, $0 }' teams.txt
printf
no crea una nueva línea después de cada registro, por lo que estamos usando \n
:
1. Bucks Milwaukee 60 22 0.732
2. Raptors Toronto 58 24 0.707
3. 76ers Philadelphia 51 31 0.622
4. Celtics Boston 49 33 0.598
5. Pacers Indiana 48 34 0.585
El siguiente comando calcula la suma de los valores almacenados en el tercer campo de cada línea:
awk '{ sum += $3 } END { printf "%d\n", sum }' teams.txt
266
Aquí hay otro ejemplo que muestra cómo usar expresiones y declaraciones de control para imprimir los cuadrados de los números del 1 al 5:
awk 'BEGIN { i = 1; while (i < 6) { print "Square of", i, "is", i*i; ++i } }'
Square of 1 is 1
Square of 2 is 4
Square of 3 is 9
Square of 4 is 16
Square of 5 is 25
Los comandos de una línea como el anterior son más difíciles de entender y mantener. Al escribir programas más largos, debe crear un archivo de programa separado:
BEGIN {
i = 1
while (i < 6) {
print "Square of", i, "is", i*i;
++i
}
}
Ejecute el programa pasando el nombre del archivo al awk
intérprete:
awk -f prg.awk
También puede ejecutar un programa awk como ejecutable utilizando la directiva shebangawk
y configurando el intérprete:
#!/usr/bin/awk -f
BEGIN {
i = 1
while (i < 6) {
print "Square of", i, "is", i*i;
++i
}
}
Guarde el archivo y hágalo ejecutable :
chmod +x prg.awk
Ahora puede ejecutar el programa ingresando:
./prg.awk
Uso de variables de shell en programas Awk
Si está utilizando el awk
comando en scripts de shell, lo más probable es que necesite pasar una variable de shell al programa awk. Una opción es encerrar el programa con comillas dobles en lugar de simples y sustituir la variable en el programa. Sin embargo, esta opción hará que su programa awk sea más complejo ya que necesitará escapar de las variables awk.
La forma recomendada de usar variables de shell en programas awk es asignar la variable de shell a una variable awk. Aquí hay un ejemplo:
num=51
awk -v n="$num" 'BEGIN {print n}'
51
Conclusión
Awk es una de las herramientas más poderosas para la manipulación de texto.
Este artículo apenas toca la superficie del lenguaje de programación awk. Para obtener más información sobre awk, consulte la documentación oficial de Gawk .
Si tiene alguna pregunta o comentario, no dude en dejar un comentario.
0 Comentarios