6. Patrones

Los patrones en awk controlan la ejecución de reglas: una regla es ejecutada cuando su patrón concuerda (matches) con el registro de entrada actual. Este capítulo habla sobre como escribir patrones.

Tipos de Patrones

Aquí se presenta un sumario de los tipos de patrones soportados en awk.

/expresión regular/

Una expresión regular como patrón. Encaja cuando el texto del registro de entrada concuerda con la expresión regular. (Ver la sección Expresiones Regulares como Patrones).

expresión

Una expresión solamente. Casa cuando su valor, convertido a número, es distinto de cero (si es un número) o no nulo (si es una cadena). (Ver la sección Expresiones como Patrones).

pat1, pat2

Un par de patrones separados por una coma, especificando un rango de registros. (Ver la sección Especificando Rangos de Registros con Patrones).

BEGIN

END

Patrones especiales para suministrar a awk información para antes del inicio del procesamiento o al final del procesamiento. (Ver la sección Los Patrones Especiales BEGIN y END).

null

El patrón vacío casa con todos y cada uno de los registros de entrada. (Ver la sección El Patrón Vacío).

El Patrón Vacío

Un patrón vacío se considera que casa con todos los registros de la entrada. Por ejemplo, el programa:

awk '{ print $1 }' Lista–BBS

imprime solamente el primer campo de cada registro.

Expresiones Regulares como Patrones

Una expresión regular, o expreg, es una forma de describir una clase de cadenas de texto. Una expresión regular encerrada entre barras (‘/’) es un patrón awk que casa con cada registro de entrada cuyo texto pertenece a esa clase.

La expresión regular más simple es una secuencia de letras, números, o ambos. Tales expresiones regulares casa con cualquier cadena que contenga dicha secuencia de letras y números. Por lo que, la expresión regular ‘foo’ casa con cualquier cadena que contenga ‘foo’. Por lo tanto, el patrón /foo/ casa con cualquier registro que contenga la cadena ‘foo’. Otros tipos de expresiones regulares te permiten expecificar clases de cadenas más complicadas.

Cómo usar Expresiones Regulares

Una expresión regular puede ser usada como un patrón encerrandola entre barras. Entonces la expresión regular es comparada contra todo el texto de cada registro. (Normalmente, solo hace falta que case parte del texto para que el casamiento tenga éxito). Por ejemplo, esto imprime el segundo campo de cada registro que contiene ‘foo’ en cualquier parte del registro:

awk '/foo/ { print $2 }' Lista–BBS

Las expresiones regulares pueden también ser usadas en expresiones de comparación. Entonces puedes especificar la cadena contra la cual casarla; no necesita que case el registro de entrada actual completamente. Estas expresiones de comparación pueden ser usadas como patrones o en sentencias if y while.

exp ~ /regexp/

Esto es cierto si la expresión exp (tomada como una cadena de caracteres) encaja con regexp. Los siguientes ejemplo encajan o seleccionan todos los registros de entrada que contengan la letra ‘J’ en cualquier posición dentrl del primer campo:

awk '$1 ~ /J/' inventario–enviado

O sino:

awk '{ if ($1 ~ /J/) print }' inventario–enviado

exp !~ /regexp/

Esto es cierto si la expresión exp (tomada como una cadena de caracteres) no concuerda con regexp. El siguiente ejemplo encaja o selecciona todos los registros de entrada cuyo primer campo no contiene la letra ‘J’ en ninguna posición:

awk '$1 !~ /J/' inventario–enviado

La parte derecha de un operador `~' o `!~' no necesita ser una expresión regular constante (por ejemplo, una cadena de caracteres entre barras). Podría ser cualquier expresión. La expresión es evaluada, y convertida si es necesario a una cadena; los contenidos de la cadena serán utilizados como expresión regular. Una expresión regular que se comporta de esta forma es llamada expresión regular dinámica. Por ejemplo:

identifier_regexp = "[A–Za–z_][A–Za–z_0–9]+"

$0 ~ identifier_regexp

fija la variable identifier_regexp a una expresión regular que describe nombres de variables de awk, y chequea si el registro de entrada encaja con esta expresión regular.

Operadores de Expresiones Regulares

Puedes combinar expresiones regulares con los siguientes caracteres, llamados operadores de expresiones regulares, o metacaracteres, para incrementar el poder y versatilidad de las expresiones regulares.

Aquí tienes una tabla de metacaracteres. Todos los caracteres que no aparecen no tienen ningún significado especial en una expresión regular.

^

Esto busca el principio de la cadena o el principio de una línea dentro de la cadena. Por ejemplo:

^@capítulo

coincide con ‘@capítulo’ al principio de una cadena, y puede ser usada para identificar comienzos de capítulos en ficheros fuentes Texinfo.

$

Esto es similar a ‘~’, pero encaja solo al final de una cadena o el final de una línea dentro de la cadena. Por ejemplo:

p$

encaja con un registro que acabe en ‘p’.

.

Esto encaja con cualquier carácter único, excepto el carácter nueva línea. Por ejemplo:

.P

encaja con cualquier carácter que vaya seguido por una ‘P’ en una cadena. Usando la concatenación podemos hacer expresiones regulares como ‘U.A’, la cual encaja con cualquier secuencia de 3 caracteres que comiencen con una ‘U’ y acaben con ‘A’.

[…]

Esto recibe el nombre de conjunto de caracteres. Encaja con cualquiera de los caracteres encerrados entre los corchetes. Por ejemplo:

[MVX]

encaja con cuales quiera de los caracteres ‘M’, ‘V’, y ‘X’ en una cadena.

Se pueden especificar rangos de caracteres utilizando un guión entre el carácter de inicio y el carácter final del intervalo de caracteres, y encerrando entre los corchetes. Por ejemplo:

[0–9]

encaja con cualquier dígito.

Para incluir cualquiera de estos caracteres `\', `]', `–' o `^' en un conjunto de caracteres, pon un ‘\’ antes del carácter en cuestión. Por ejemplo:

[d\]]

encaja con ‘]’ o ‘d’.

Este tratamiento de ‘\’ es compatible con otras implementaciones de awk pero incompatible con la expecificación POSIX propuesta para awk. El borrador actual especifica el uso de la misma sintáxis usada en egrep.

Podríamos cambiar gawk para que encajase con el estándar, una vez que estuviésemos seguros de que no volverá a cambiar. Mientras tanto, la opción ‘–a’ especifica la sintaxis de awk tradicional descrita anteriormente (la cual es también la sintaxis por defecto), mientras que la opción ‘–e’ especifica la sintaxis egrep. (Ver la sección Opciones de la línea de comandos).

En la sintáxis egrep, la barra invertida no tiene sintácticamente significado especial dentro de las llaves. Esto significa que tienen que ser usados trucos especiales para representar los caracteres ‘]’, ‘–’ y ‘^’ como miembros de un conjunto de caracteres.

Para buscar un coincidencia del carácter ‘–’, escríbelo como ‘–––’, lo cual es un rango que contiene únicamente el carácter  ‘–’. Podrías también dar ‘–’ como el primer o el último carácter del conjunto. Para buscar una coincidencia del carácter ‘^’, ponlo en cualquier lugar excepto como el primer carácter de un conjunto. Para buscar una coincidencia del carácter ‘]’, haz que sea el primer carácter del conjunto. Por ejemplo:

[]d^]

encaja con ‘]’, ‘d’ o ‘^’.

[^…]

Esto es el conjunto de caracteres complementario. El primer carácter después del ‘[’ debe ser un ‘^’. Encaja con cuales quiera caracteres excepto aquellos que se meten entre los corchetes. Por ejemplo:

[^0–9]

encaja con cualquier carácter que no sea un dígito.

¦

Este es el operador alternación y se usa para especificar alternativas. Por ejemplo:

^P¦[0–9]

encaja con cualquier cadena que encaje con ‘^P’ o con ‘[0–9]’. Esto significa que encaja con cualquier cadena que contenga un dígito o comience por ‘P’.

La alternación se aplica a la expresión regular posible más grande a cada lado.

(…)

Los paréntesis se usan para agrupar expresiones regulares del mismo modo que en las aritméticas. Pueden ser usados para concatenar expresiones regulares que contengan el operador alternación ‘¦’.

*

Este símbolo significa que la expresión regular precedente se va a repetir tantas veces como sea posible para encontrar una concordancia. Por ejemplo:

ph*

aplica el símbolo ‘*’ a la ‘h’ precedente y busca la concordancia de una ‘p’ seguida por cualquier número de haches. También encajará con una única ‘p’ que no vaya seguida por ninguna ‘h’.

El ‘*’ repite la expresión precedente más pequeña posible. (use paréntesis si deseas repetir una expresión más grande) Encuentra tantas repeticiones como sea posible. Por ejemplo:

awk '/\(c[ad][ad]*r x\)/ { print }' sample

imprime cada registro de la entrada que contenga cadenas de la siguiente forma ‘(car x)’, ‘(cdr x)’, ‘(cadr x)’, y así sucesivamente.

+

Este símbolo es similar a ‘*’, pero la expresión precedente debe encajar al menos una vez. Esto significa que:

wh+y

encajará con ‘why’ y ‘whhy’ pero no con ‘wy’, donde sin embaro ‘wh*y’ encajaría con las tres combinaciones. Esta es una forma más simple de escribir el último ejemplo ‘*’:

awk '/\(c[ad]+r x\)/ { print }' sample

?

Este símbolo es similar a ‘*’, pero la expresión regular precedente puede encajar una vez o ninguna. Por ejemplo:

fe?d

encajará con ‘fed’ o ‘fd’ y nada más.

\

Esto se usa para suprimir el significado especial de un carácter en un matching. Por ejemplo:

\$

busca una coincidencia del carácter ‘$’.

Las secuencias escape usadas para constantes de cadena (Ver la sección Expresiones Constantes) son válidas en expresiones regulares también; ellas son también precedidas por un ‘\’.

En las expresiones regulares, los operadores ‘*’, ‘+’ y ‘?’ tienen la precedencia mayor, seguidos por la concatenación, y finalmente por ‘¦’. Como en las aritméticas, los paréntesis pueden cambiar el modo en que se agrupen los operadores.

Sensibilidad a Mayúsculas en el Matching

La sensibilidad a mayúsculas es normalmente significativa en expresiones regulares, también cuando casa caracteres ordinarios (por ejemplo, no con metacaracteres), y dentro de conjunto de caracteres. Por lo que una ‘w’ en una expresión regular encaja solamente con una ‘w’ minúscula y nunca con una ‘W’ mayúscula.

La forma más fácil de hace una búsqueda o encaje insensible a mayúsculas es usar el conjunto de caracteres: ‘[Ww]’. Sin embargo, esto puede ser embarazoso si necesitas usarlo a menudo; y puede hacer que la expresión regular sea más ilegible. Existen otras dos alternativas que podrías preferir.

Una forma de realizar una búsqueda insensible a mayúsculas en un punto en particular del programa es convertir el dato a un único tipo (mayúsculas o minúsculas), usando las funciones empotradas para manejo de cadenas tolower o toupper (que serán explicadas posteriormente en la Sección Funciones Implícitas (Built–in) para Manipulación de Cadenas). Por ejemplo:

tolower($1) ~ /foo/  { ... }

convierte el primer campo a minúsculas antes de realizar una búsqueda o comparación contra dicho campo.

Otro método es fijar la variable IGNORECASE a un valor distinto de cero (ver sección 12. Variables Implícitas (Built–in). Cuando IGNORECASE es distinta de cero, todas las operaciones de expresiones regulares son insensibles a mayúsculas/minúsculas. Cambiando el valor de la variable IGNORECASE se puede controlar de forma dinámica la sensibilidad a mayúsculas/minúsculas de tu programa en tiempo de ejecución. La sensibilidad a mayúsculas/minúsculas está activada por defecto porque la variable IGNORECASE (como la mayoría de las variables) es inicializada a cero.

x = "aB"

if (x ~ /ab/) ...   # esta comprobación fallará

IGNORECASE = 1

if (x ~ /ab/) ...   # esta comprobación tendrá éxito

Normalmente no puedes usar IGNORECASE para hacer que ciertas reglas sean insensibles a mayúsculas/minúsculas y otras reglas sean sensibles, porque no hay forma de fijar el valor de IGNORECASE solamente para el patrón de una regla en particular. Para hacer esto, debes usar los conjuntos de caracteres o tolower. Sin embargo, una cosa que puedes hacer solamente con IGNORECASE es activar o desactivar la sensibilidad a mayúsculas/minúsculas para todas las reglas de una vez.

IGNORECASE puede ser fijado en la línea de comando, o en una regla BEGIN. Fijar la variable IGNORECASE en la línea de comando puede ser una forma de hacer a un programa insensible a las mayúsculas/minúsculas sin tener que editarlo.

El valor de IGNORECASE no tiene ningún efecto si gawk está en modo compatibilidad (Ver la sección 14. Invocación de awk). En modo compatibilidad la diferencia entre mayúsculas y minúsculas es siempre significativa.

Expresiones de Comparación como Patrones

            Los patrones de comparación chequean relaciones tales como igualdad entre dos cadenas o números. Son un caso especial de patrones de expresiones (ver la Sección Expresiones como Patrones). Ellos son escritos con operadores relacionales, los cuales son un superconjunto de los mismos en C. Aquí tienes una tabla de ellos:

x < y

Verdad si x es menor que y.

x <= y

Verdad si x es menor o igual que y.

x > y

Verdad si x es mayor que y.

x >= y

Verdad si x es mayor o igual que y.

x == y

Verdad si x es igual a y.

x != y

Verdad si x no es igual a y.

x ~ y

Verdad si x encaja con la expresión regular descrita por y.

x !~ y

Verdad si x no encaja con la expresión regular descrita por y.

Los operandos de un operador relacional son comparados como números si ambos son números. Si no ellos son convertidos y comparados como cadenas (ver la sección Conversiones de Cadenas y Números). Las cadenas son comparadas comparando el primer carácter de ambas, después el segundo carácter de ellas y así sucesivamente, hasta que encuentre una diferencia. Si las dos cadenas son iguales hasta que se acaba la cadena más corta, la cadena más corta se considera menor que la más larga. Por lo que “10” es menor que “9”.

El operando izquierdo de los operadores ‘~’ y ‘!~’ es una cadena. El operador derecho es o una expresión regular constante encerrada entre barras (/expreg/), o cualquier expresión, cuyo valor como cadena se usa como una expresión regular dinámica (Ver la sección Cómo usar Expresiones Regulares)

El siguiente ejemplo imprime el segundo campo de cada registro de entrada cuyo primer campo valga justamente ‘foo’.

awk '$1 == "foo" { print $2 }' Lista–BBS

Constrasta esto con el siguiente encaje de expresión regular, el cual aceptaría cualquier registro con un primer campo que contuviese la cadena ‘foo’.

awk '$1 ~ "foo" { print $2 }' Lista–BBS

o, equivalentemente, este:

awk '$1 ~ /foo/ { print $2 }' Lista–BBS

Operadores Booleanos como Patrones

Un patrón booleano es una expresión la cual combina otros patrones usando los operadores booleanos “o” (‘¦¦’), “y” (‘&&’) y “not” (‘!’). Donde los patrones booleanos encajan con un registro de entrada dependiendo de si encajan o no los subpatrones.

Por ejemplo, el siguiente comando imprime todos los registros en el fichero de entrada ‘Lista–BBS’ que contengan tanto ‘2400’ como ‘foo’.

awk '/2400/ && /foo/' Lista–BBS

El siguiente comando imprime todos los registros en el fichero de entrada ‘Lista–BBS’ que contengan ‘2400’ o ‘foo’ o ambos.

awk '/2400/ ¦¦ /foo/' Lista–BBS

El siguiente comando imprime todos los registros del fichero de entrada ‘Lista–BBS’ que no contengan la cadena ‘foo’.

awk '! /foo/' Lista–BBS

Dese cuenta de que los patrones booleanos son un caso especial de los patrones de expresión (Ver la sección Expresiones como Patrones); son expresiones que usan los operadores booleanos. Ver la sección Expresiones Booleanas, para una información completa sobre los operadores booleanos.

El subpatrón de un patrón booleano pueden ser expresiones regulares constantes, o cualquier otra expresión gawk. Los patrones de rango no son expresiones, por lo que no pueden aparecer dentro de los patrones booleanos. Del mismo modo, los patrones especiales BEGIN y END, los cuales nunca encajan con ningún registro de entrada, no son expresiones y no pueden aparecer dentro de los patrones booleanos.

Expresiones como Patrones

Cualquier expresión awk es también válida como un patrón en gawk. Entonces el patrón “encaja” si el valor de la expresión es distinto de cero (si es un número) o distinto de nulo (si es una cadena).

La expresión es evaluada de nuevo cada vez que la regla se chequea contra un nuevo registro de entrada. Si la expresión utiliza campos tales como $1, el valor depende directamente del texto del registro de entrada nuevo, de otra forma, depende solo de lo que haya ocurrido hasta el momento en la ejecución del programa awk, pero eso aún podría ser útil.

Los patrones de comparación son realmente un caso especial de este. Por ejemplo, la expresión $5 == “foo” tiene el valor 1 cuando el valor de $5 es igual a “foo”, y en cualquier otro caso 0; por lo tanto, esta expresión como patrón encaja cuando los dos valores son iguales.

Los patrones booleanos son también casos especiales de los patrones de expresión.

Una expresión regular constante como patrón es también un caso especial de un patrón de expresión. /foo/ encaja con cualquier registro que contenga ‘foo’.

Otras implementaciones de awk son menos generales que gawk: permiten expresiones de comparación, y combinaciones booleanas (opcionalmente con paréntesis), pero no necesariamente otros tipos de expresiones.

Especificando Rangos de Registros con Patrones

Un rango de patrones está formado por dos patrones separados por una coma, de la forma patroninicio, patronfinal. Encaja con rangos de registros de entrada consecutivos. El primer patrón patroninicio controla donde comienza el rango, y el segundo patrónfinal controla donde acaba. Por ejemplo,

awk '$1 == "on", $1 == "off"'

imprime todos los registros entre ‘on’/‘off’, ambos incluídos.

En más detalle, un patrón de rango comienza chequeando el patróninicio contra los registros de entrada; cuando un registro concuerda con patróninicio, se activa el patrón de rango y te sacará todos los registros de entrada hasta que encuentra una línea que encaja con el patrónfinal. A continuación vuelve a buscar el patróninicio a partir de la siguiente línea a la línea que concordó con el patrónfinal y así sucesivamente.

El registro que activa el rango de patrones y el que lo desactiva, ambos concuerdan y son incluidos dentro del patrón. Si no se desean que se operen o tengan en cuenta dichos patrones, puedes escribir una sentencia if en la acción de la regla para discriminarlos.

Es posible que exista un mismo registro que sea el que active y desactive el rango de patrón, si ambas condiciones son satisfechas por dicho registro. Entonces la acción se ejecuta solamente para dicho registro.

Los Patrones Especiales BEGIN y END

BEGIN y END son patrones especiales. Ellos no son usados para encajar con registros de entrada. En su lugar, ellos son usados para suministrar al script awk qué hacer antes de empezar a procesar y después de haber procesado los registros de la entrada. Una regla BEGIN se ejecuta una vez, antes de leer el primer registro de entrada. Y la regla END se ejecuta una vez después de que se hayan leído todos los registros de entrada. Por ejemplo:

awk 'BEGIN { print "Análisis de `foo'" }

     /foo/ { ++foobar }

     END   { print "`foo' aparece " foobar " veces." }' Lista–BBS

Este programa averigua cuantas veces aparece la cadena ‘foo’ en el fichero de entrada ‘Lista–BBS’. La regla BEGIN imprime un título para el informe. No hay necesidad de usar la regla BEGIN para inicializar el contador foobar a cero, ya que awk lo hace por nosotros automáticamente (ver la sección Variables).

La segunda regla incrementa el valor de la variable foobar cada vez que se lee de la entrada un registro que contiene el patrón ‘foo’. La regla END imprime el valor de la variable foobar al final de la ejecución.

Los patrones especiales BEGIN y END no pueden ser usados en rangos o con operadores booleanos. Un programa awk podría tener múltiples reglas BEGIN y/o END. Ellas son ejecutadas en el mismo orden que aparecen, todas las reglas BEGIN al principio y todas las reglas END al final.

Las secciones BEGIN y END múltiples pueden ser útiles para escribir funciones de librería, ya que cada librería puede tener su propias reglas BEGIN y END para hacer sus propias inicializaciones y/o limpieza. Avertirle que el orden en el cual las librerías son nombradas en la línea de comandos controla el orden en el que son ejecutadas las reglas BEGIN y END. Por lo tanto tienes que tener cuidado cuando escribas tales reglas en ficheros de librerías para que te dé igual el orden en el que las incluyas en la ejecución. Ver la sección 14. Invocación de awk para más información acerca del uso de funciones de librería.

Si un programa awk tiene solamente una regla BEGIN, y ninguna otra regla, entonces el programa se sale una vez que se ha ejecutado la regla BEGIN, sin llegar a leer los registros del fichero de entrada. Sin embargo, si existe también una regla END, entonces se leerán los registros de la entrada, incluso aunque no haya ninguna otra regla en el programa. Esto es necesario en caso de que la regla END chequee el valor de la variable empotrada NR (número de registros leídos).

Las reglas BEGIN y END deben tener acciones; no existen acciones por defecto para estas reglas, ya que no hay ningún registro actual cuando son ejecutadas.

   
Índice
Manual