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.
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).
Un patrón vacío se considera que casa con todos los
registros de la entrada. Por ejemplo, el programa:
awk '{ print $1 }' ListaBBS
imprime solamente el primer campo de cada registro.
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.
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 }' ListaBBS
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/' inventarioenviado
O sino:
awk '{ if ($1 ~ /J/) print }' inventarioenviado
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/' inventarioenviado
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 = "[AZaz_][AZaz_09]+"
$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.
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:
[09]
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:
[^09]
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¦[09]
encaja con cualquier cadena que encaje con ^P o con [09]. 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.
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 (Builtin) 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 (Builtin).
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.
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 }' ListaBBS
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 }' ListaBBS
o, equivalentemente, este:
awk '$1 ~ /foo/ { print $2 }' ListaBBS
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 ListaBBS que contengan tanto 2400 como
foo.
awk '/2400/ && /foo/' ListaBBS
El siguiente comando imprime todos los registros en el fichero
de entrada ListaBBS que contengan 2400 o foo o ambos.
awk '/2400/ ¦¦ /foo/' ListaBBS
El siguiente comando imprime todos los registros del fichero
de entrada ListaBBS que no contengan la cadena foo.
awk '! /foo/' ListaBBS
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.
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.
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.
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." }' ListaBBS
Este programa averigua cuantas veces aparece la cadena
foo en el fichero de entrada ListaBBS. 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.
Manual |