TuxUbuntu

Compartamos conocimiento

Jun
17

El comando awk

Entrada por TuxUbuntu en Comandos

AWK es un lenguaje de programación diseñado para procesar datos basados en texto, ya sean ficheros o flujos de datos. El nombre AWK deriva de los apellidos de los autores: Alfred Aho, Peter Weinberger, y Brian Kernighan.

awk, cuando está escrito todo en minúsculas, hace referencia al programa de Unix que interpreta programas escritos en el lenguaje de programación AWK.

AWK es ejemplo de un lenguaje de programación que usa ampliamente el tipo de datos de listas asociativas (es decir, listas indexadas por cadenas clave), y expresiones regulares. El poder, brevedad y limitaciones de los programas de AWK y los guiones de sed inspiraron a Larry Wall a escribir Perl. Debido a su densa notación, todos estos lenguajes son frecuentemente usados para escribir programas de una linea.

Veamos un ejemplo practico antes de pasar a una conotacion mas amplia del lenguaje AWK. Supongamos que tenemos un archivo de texto como el que sigue:

Mario   DF             Enero       Ingeniero   26
Jorge   Buenos Aires   Diciembre   Derecho     32
Luis    Caracas        Agosto      Medico      27
Pedro   Copa Cabana    Marzo       Dentista    40

pero solo deseamos seleccionar el nombre y edad, entonces solo debemos escribir en una Terminal

awk '{print $1,$5}'  > data.txt

y nos creara un archivo data.txt como el que sigue

Mario   26
Jorge   32
Luis    27
Pedro   40

Ahora bien si lo que deseamos es ordenar las columnas del archivo de otro modo es tan simple como hacer, para el archivo original

awk '{print $1,$5,$2,$4,$3}'  > data.txt

y nos creara un archivo data.txt como el que sigue

Mario   26   DF             Ingeniero   Enero
Jorge   32   Buenos Aires   Derecho     Diciembre
Luis    27   Caracas        Medico      Agosto
Pedro   40   Copa Cabana    Dentista    Marzo

Si quieren conocer un poco mas solo sigan leyendo.

Estructura de los programas AWK

Generalmente hablando, a AWK se le dan dos piezas de datos: un fichero de órdenes y un fichero primario de entrada. Un fichero de órdenes (que puede ser un fichero real, o puede ser incluido en la invocación de AWK desde la linea de comandos) contiene una serie de órdenes que le dicen a AWK cómo procesar el fichero de entrada. El fichero primario de entrada es normalmente texto formateado de alguna manera; puede ser en un fichero real, o puede ser leído por AWK de la entrada estándar (teclado). Un programa AWK típico consiste en una serie de líneas, cada una de la forma

/patrón/ { acción }

donde patrón es una expresión regular y acción es una orden. La mayoría de las implementaciones de AWK usan expresiones regulares extendidas por defecto. AWK mira a lo largo del fichero de entrada; cuando encuentra una línea que coincide con el “patrón”, ejecuta la(s) órdenes(s) indicadas en “acción”. Las formas alternativas incluyen:

BEGIN { acción }
Ejecuta las órdenes acción al comienzo de la ejecución, antes de que los datos comienzen a ser procesados.
END { acción }
Similar a la forma previa pero ejecuta las órdenes acción después de que todos los datos sean procesados.
/patrón/
Imprime las líneas acordes al patrón.
{ acción }
Ejecuta acción por cada línea en la entrada.

Cada una de estas formas pueden ser incluidas varias veces en un archivo. El fichero es procesado de manera progresiva, entonces si hubiera dos declaraciones “BEGIN”, sus contenidos serán ejecutados en orden de aparición. Las declaraciones “BEGIN” y “END” no necesitan estar en forma ordenada.

AWK fue creado como un reemplazo a los algoritmos escritos en C para métodos de análisis de texto.

Comandos de AWK

Los comandos de AWK son las declaraciones sustituidas por acción en los ejemplos anteriores. Los comandos de AWK pueden incluir llamadas a funciones, asignación de variables, cálculos, o cualquier combinación de estas. AWK contiene soporte propio para muchas funciones; muchas otras son provistas por las distintas versiones de AWK. Incluso algunas versiones soportan la inclusión de librerías dinámicamente enlazadas, que pueden proveer aún más funciones.

Por claridad los corchetes ( { } ) serán omitidos en los siguientes ejemplos.

El comando print

El comando print es usado para imprimir texto. La forma más simple de este comando es

print

Esto muestra el contenido de la línea actualmente procesada. En AWK las líneas son divididas en campos, y estos pueden ser operados individualmente:

print $1
Muestra el primer campo de la línea actual
print $1, $3
Muestra el primer y tercer campo de la línea actual, separados por una cadena predefinida, separador de campos de salida o OFS (por sus siglas en inglés), cuyo valor predefinido es un carácter de espacio (’ ‘).

Aunque esta sintaxis ($#) puede sugerir que se traten de variables (el símbolo $ es indicador de variables en otros lenguajes), hacen referencia a los campos de la línea actual. Un caso especial, $0, se refiere a la línea entera. De hecho, los comandos “print” y “print $0” resultan similares.

El comando print puede también imprimir el resultado de cálculos o funciones invocadas:

print 3+2
print foobar(3)
print foobar(variable)
print sin(3-2)

La salida puede ser enviada a un archivo:

print “expresión” > “nombre de archivo”

Por ejemplo abre una terminal y escribe lo siguiente

awk '{ print 3+2 }'

dale Enter dos veces y veras que te imprime el valor de la operacion, para terminar Ctrl+C

Variables

Los nombres de variables pueden usar cualquier combinación de los caracteres [A-Za-z0-9_], con la única excepción de las palabras clave del lenguaje. Los operadores + – * / son suma, resta, multiplicación y división respectivamente. Para la concatenación, basta con colocar dos variables (o cadena constante) junto a cualquier otra, opcionalmente con un espacio intermedio. Las cadenas son delimitadas por comillas dobles. No es necesario finalizar las ordenes con punto y coma. Se pueden añadir comentarios del programa usando # como primer carácter en una línea.

Funciones definidas por el usuario

De manera similar al C, la definición de funciones consiste en la clave function, el nombre de la función, los argumentos de la función y el cuerpo de la misma, ejemplo:

function anyadir_tres (numero, temporal) {       # Los identificadores no contienen la letra ñ
temporal = numero + 3                            # Tampoco pueden tener acentos
return temporal
}

Podemos invocar la función así:

print anyadir_tres(36)                           # Imprime 39

Las funciones pueden tener variables definidas localmente. Los nombres de estas son añadidos al final de la lista de argumentos, aunque los valores de estas deben ser omitidos al llamar la función. Es conveniente indentar las variables locales en la lista de argumentos para indicar dónde terminan los parámetros y dónde comienzan las variables locales.

Ejemplos

Hola mundo

Este es un programa “Hola mundo” muy simple escrito en AWK:

BEGIN { print "Hola mundo!"; exit }

Imprimir lineas mayores a 80 caracteres

Imprime todas las líneas con más de 80 caracteres. Nótese que la acción por defecto es imprimir la línea actual.

length > 80

Contador de palabras

Cuenta las palabras en la entrada y muestra la cantidad de líneas, palabras y caracteres.

{ w += NF; c += length}
END { print NR, w, c }

Frecuencia de palabras

Este programa usa listas enlazadas para determinar la cantidad de veces que cada palabra aparece en el texto.

BEGIN { FS="[^a-zA-Z]+"}
{ for (i=1; i<=NF; i++) words[tolower($i)]++ }

END{ for (i in words) print i, words[i] }

Scripts

Como cualquier otro lenguaje de programación, se pueden escribir programas AWK autocontenidos usando la sintaxis de líneas de shebang.

Por ejemplo, un comando UNIX llamado holamundo.awk que imprima el texto “Hola mundo!” podría ser escrito de la siguiente manera:

#!/usr/bin/awk -f
BEGIN { print "Hello, world!"; exit }

  1. Alejandro Dijo:
    March 25 2009 a las 2:04 pm

    Excelente aporte,
    tengo una consulta, estoy aprendiendo esto de AWK, pero tengo una duda. Si tengo una sola linea de texto, Ej.
    nombre1;apellido1;telefono1,nombre2;apellido2;telefono2,nombre3;apellido3;telefono3,nombre4;apellido4;telefono4

    ahora deseo obtener la salida seperando los campos y los registros. Ya pude por medio de FS= definir el separador de los campos, pero como le especifico hasta donde llega el registro y como me imprime los otros campos del registro 2

    Saludos

    Gracias



Agrega un comentario