Especificando como están separados los campos AWK

El modo en el que awk divide los registros de entrada en campos es controlada por el separador de campo, el cual es un carácter simple o una expresión regular. Awk recorre el registro de entrada en búsqueda de coincidencias del separador de campos; los campos son el texto que se encuentra entre dichos separadores de campos encontrados. Por ejemplo, si el separador de campos es ‘oo’, entonces la siguiente línea:

moo goo gai pan

será particionada en tres campos: `m', ` g' y ` gai pan'.

El separador de campos está representado por la variable implícita FS. ¡Que tomen nota los programadores de la Shell! Awk no usa el nombre IFS el cual es usado por la shell. Puedes cambiar el valor de FS en el programa awk con el operador asignación, ‘=’. A menudo el momento adecuado para hacer esto es el principio de la ejecución, antes de que se procese ninguna entrada, de forma que el primer registro se lea con el separador adecuado. Para hacer esto, use el patrón especial BEGIN . Por ejemplo, aquí hemos fijado el valor de la variable FS a la acadena “,”:

awk 'BEGIN { FS = "," } ; { print $2 }'

Dada la siguiente línea,

John Q. Smith, 29 Oak St., Walamazoo, MI 42139

Este programa awk extrae la cadena `29 Oak St.'.

Algunas veces tus datos de entrada contendrán caracteres separadores que no separen los campos de la forma que tu pensabas que debieran estar separados. Por ejemplo, los nombres de personas en el ejemplo que hemos estado usando podría tener un título o sufijo acoplado, tal como `John Q. Smith, LXIX'. Para la entrada que contuviese dicho nombre:

John Q. Smith, LXIX, 29 Oak St., Walamazoo, MI 42139

El programa de ejemplo anterior extraería `LXIX', en lugar de `29 Oak St.'. Si estabas esperando que el programa escribiese la dirección, serías sorprendido. Así que elige la disposición de tus datos y separadores de campos cuidadosamente para prevenir tales problemas.
Como ya sabes, por defecto, los campos son separados por secuencias de espacios en blanco (espacios y tabuladores), no por espacios simples: dos espacios en una fila no delimitan un campo vacío. El valor por defecto del separador de campos es una cadena “ “ que contiene un único espacio. Si este valor fuese interpretado de la forma usual, cada carácter espacio separaría campos, de forma que dos espacios en una fila crearían un campos vacío entre ellos. La razón por lo que esto no ocurre es porque un espacio simple como valor de FS es un caso especial: se toma para especificar la manera por defecto de deliminar campos.
Si FS es cualquier otro carácter simple, tal y como “,”, cada ocurrencia de dicho carácter separa dos campos. Dos ocurrencias consecutivas delimitan un campo vacío. Si el carácter ocurre al comienzo o al final de la línea, eso también  delimita un campo vacío. El carácter espacio es el único carácter que no sigue estas reglas.
Más generalmente, el valor de FS podría ser una cadena que contuviese una expresión regular. Entonces cada coincidencia en el registro de la expresión regular separa campos. Por ejemplo, la asignación:

FS = ", \t"

Hace que cada área de una línea de entrada que consista en una coma seguida de un espacio y un tabulador sea un separador de campo (‘\t’ representa el tabulador).
Para un ejemplo menos trivial de una expresión regular, supón que deseas que los espacios simples separen los campos de la misma forma que lo harían unas comas si fuesen usadas. Le podrías asignar a FS el valor “[ ]”. Esta expresión regular concuerda con un único espacio y nada más.
El valor de FS puede ser fijado en la línea de comando. Use el argumento ‘ -F’ para hacerlo. Por ejemplo:

awk -F, 'program' input-files

fija FS para que sea el carácter ‘,’. Dese cuenta de que el argumento aparece en mayúsculas ‘ -F’. Esto contrasta con ‘-f’, el cual especifica un fichero que contiene un programa awk. La distinción entre mayúsculas y minúsculas es significativa en las opciones de comando: las opciones ‘-F’ y ‘-f’ no tienen nada que ver la una con la otra. Puedes usar ambas opciones al mismo tiempo para fijar el argumento FS y para decirle a awk que el programa se encuentra en un determinado fichero.

Un caso especial, en modo compatibilidad, si el argumento a ‘-F’ es ‘t’, entonces el FS es fijado al carácter tabulador. (Esto es porque si tú tecleas ‘-F\t’, sin las comillas, en el shell, el carácter ‘\’ es eliminado, de forma que awk supone que tú realmente quieres que tus campos estén separados por tabuladores, y no por t’s. Use ‘FS=”T” en la línea de comando si deseas realmente que tus campos aparezcan separados por t’s.)

Por ejemplo, utilicemos un fichero de programa awk llamado ‘baud.awk’ que contiene el patrón /300/, y la acción ‘print $1’. Aquí se presenta el programa:

/300/   { print $1 }

Fijemos también el valor de FS al carácter ‘-‘, y ejecute el programa sobre el fichero ‘Lista-BBS’ El siguiente comando imprime una lista de los nombres del bulletin boards que operan a 300 baudios y los tres primeros dígitos de sus números de teléfono:

awk -F- -f baud.awk Lista-BBS

Produce la siguiente salida:

aardvark alpo 555
barfly 555
bites 555
camelot 555
core 555
fooey 555
foot 555
macfoo 555
sdace 555
sabafoo 555

Dese cuenta de la segunda línea de la salida. Si chequeas el fichero original, verás que la segunda línea presenta lo siguiente:

alpo-net 555-3412 2400/1200/300 A

El guíon ‘-‘ como parte del nombre del sistema fue utilizado como separador de campo, en lugar del guión que aparecía en el número de teléfono que era lo que se pretendía. Esto te demuestra porqué tienes que ser cuidadoso a la hora de elegir tus separadores de campo y registro.
El siguiente programa busca en el fichero de sistema password, e imprime las entrada de aquellos usuarios  que no tiene password:

awk -F: '$2 == ""' /etc/passwd

Aquí usamos la opción ‘-F’ de la línea de comando para fijar el separador de campo. Advierta que los campos en ‘/etc/passwd’ están separados por dos puntos. El segundo campo representa una password de usuario encriptada, pero si el campo está vacío, dicho usuario no tiene password.

Publicar un comentario

0 Comentarios