Está en la página 1de 20

sort

Ordenar lneas de los archivos de entrada a partir de criterios de ordenacin. Los espacios en blanco son
tomados por defecto como separadores de campo.
Su sintaxis es de la forma:
sort [opciones] [archivo]

Alguno de sus opciones son:

-b Ignora espacios en blanco precedentes.


-d Ordena ignorando todos los caracteres salvo caracteres letras, nmeros y espacios.
-f considera iguales las maysculas y minsculas.
-n ordena por valor numrico.
-r invertir el orden.
-k n1,[n2] Especifica un campo como clave de ordenacin, comienza en n1 y acaba en n2; los nmeros de
campo empiezan en 1. En versiones antiguas exista la opcin +1, la cual indicaba a sort que deba ordenarse
tomando la segunda columna de datos, usndose +2 para la tercera y as sucesivamente, (los nmeros de
campo empezaban en 0).
-o salida.txt Escribir el resultado en salida.txt.

Ejemplos de uso, para lo cual se tomara como ejemplo el archivo pepe.txt cuyo contenido es:
# cat pepe.txt
15 windows
16 acer
2 actualizacion
1 actualizada
3 admiral
2 www
1 agregar
10 aires
1 al
1 algunos
1 empleos
60 en
2 equipo
45 archivos
3 word
sort pepe.txtOrdena el archivo pepe.txt
# sort pepe.txt
10 aires
15 windows
16 acer
1 actualizada
1 agregar
1 al
1 algunos
1 empleos
2 actualizacion
2 equipo
2 www
3 admiral
3 word
45 archivos
60 en
sort -k 1 pepe.txtOrdena el archivo usando el primer campo como clave de ordenacin. Tiene el mismos
efecto que sort pepe.txt
# sort -k 1 pepe.txt
10 aires
15 windows
16 acer
1 actualizada
1 agregar
1 al
1 algunos
1 empleos
2 actualizacion
2 equipo
2 www
3 admiral
3 word
45 archivos
60 en
sort -k 2 pepe.txtOrdena el archivo usando el segundo campo como clave de ordenacin.
# sort -k 2 pepe.txt
16 acer
2 actualizacion
1 actualizada
3 admiral
1 agregar
10 aires
1 al
1 algunos
45 archivos
1 empleos
60 en
2 equipo
15 windows
3 word
2 www
sort -n pepe.txtOrdena el archivo por valor numrico.
# sort -n pepe.txt
1 actualizada
1 agregar
1 al
1 algunos
1 empleos
2 actualizacion
2 equipo
2 www
3 admiral
3 word
10 aires
15 windows
16 acer
45 archivos
60 en
sort -nr pepe.txtOrdena el archivo por valor numrico de mayor a menor (invierte el orden).
# sort -nr pepe.txt
60 en
45 archivos
16 acer
15 windows
10 aires
3 word
3 admiral
2 www
2 equipo
2 actualizacion
1 empleos
1 algunos
1 al
1 agregar
1 actualizada
sort -t @ -k 2,2 pp.txt ordena el archivo pp.txt por el segundo campo, y el separador de campo que utilizo es
el @ arroba.

Un ejemplo de uso prctico es si tengo una lista desordenada (de por ejemplo una palabra por fila) y quiero
averiguar cuantas veces se repite cada palabra, para lo cual puede usar el comando:
sort -bdf lista | uniq -ic | sort -nr
Donde sort -bdf lista ordenar la lista, para que el comando uniq -ic pueda contar el nmero de lneas iguales
(considera iguales las maysculas y minsculas), por ltimo ejecuto sort -nr para que ordene la lista por la
palabra que se repite ms.
# cat ejemplo.txt
mama
pepe
hola
Hola
pepe
Hola
si
no
Mama
www
# sort -bdf ejemplo.txt | uniq -ic | sort -nr
3 hola
2 pepe
2 mama
1 www
1 si
1 no

Este comando es utilizado en conjunto con el comando uniq, ya que para encontrar lineas duplicadas
consecutivas primero hay que ordenar el contenido del archivo.

Utilizado para extraer datos y generar reportes

EL $ NOS EXTRAE LA INFORMACION DE LA COLUMNA de acuerdo a la posicin indicada: ejemplo si


utilizo $3 nos mostrara la informacin de la columna 3

esta utilidad permite procesar secuencialmente uno o varios archivos, los cuales
constituyen la informacin entrante para awk. El contenido de cada una de las lneas de la
entrada se compara con una o varias plantillas, en las que debe especificarse un patrn de
bsqueda. A cada patrn se le asocia una accin, que, normalmente, procesa la
informacin entrante y la enva a la salida estndar.

Por tanto, los usos tpicos de awk se centran en la seleccin de registros de un archivo en
funcin de uno o varios criterios de bsqueda. Si solamente resultara relevante una parte
del registro seleccionado, tambin sera posible separarla e ignorar el resto.

La informacin "saliente" se puede transformar segn las necesidades del usuario, por lo
que es posible crear informes con muy poco esfuerzo de programacin.
La sintaxis es muy semejante a la del lenguaje C, con la particularidad de que, al
ser awk un intrprete, no es necesario pasar por procesos de compilacin y linkedicin. El
rendimiento de awk no es comparable al de un ejecutable, pero, dada la orientacin al
proceso secuencial de archivos, esta circunstancia solamente es relevante en condiciones
extremas.

Awk puede, adems, leer y grabar simultneamente otros archivos, adems de la entrada y
salida estndar. Otras capacidades avanzadas quedan, por su mayor dificultad, fuera del
alcance de este artculo.

Conviene, finalmente, recalcar la circunstancia de que awk solamente procesa archivos de


texto. Para manejar los datos de una hoja Excel o de cualquier otro documento en
formato propietario es necesario exportar la informacin a algn formato de texto.

Prerrequisitos

Se presupondr en adelante que el lector dispone de alguna variedad


de UNIX (permtaseme un inciso para reconocer el mrito del pedante annimo que acu
la expresin sabores de UNIX)

No se requiere el uso de una shell concreta. En los ejemplos se utiliza bash por ser capaz
de interpretar caracteres de control escritos con la sintaxis de escape con barra invertida.

Y, evidentemente, se precisa disponer de awk. Si se abre una sesin en la consola o una


ventana de terminal se averiguar facilmente la presencia de awk en la mquina tecleando
la informacin que aparece en tipografa negrita de paso fijo:

$ awk

Usage: awk [-f programfile | 'program'] [-F fieldsep] [-v var=value] [files]

Parmetros en tiempo de ejecucin

Awk sigue, como hemos indicado, un guin previamente escrito por el programador. Est
compuesto por plantillas, que indican --mediante una expresin-- qu registros se desea
procesar, y --mediante una accin-- qu proceso se pretende realizar con los registros
previamente seleccionados.

Se puede escribir el guin directamente en la lnea de mandatos, encerrado entre comillas


simples, o en un archivo de texto separado. Si se opta por la segunda opcin, debe
escribirse el nombre del archivo tras el parmetro f. La f debe ser minscula
obligatoriamente. Por tanto, cualquiera de las dos formas mostradas a continuacin
produce resultados equivalentes:

$ awk { print $1 } entrada.txt


$ awk -f primer.awk entrada.txt

Ms adelante se mostrar cmo awk procesa cada registro como una sucesin de campos
separados por un carcter determinado que indica dnde termina un campo y empieza el
siguiente. La situacin ms habitual es aquella en la cual cada registro contiene una frase y
los campos son las palabras de la frase. El carcter delimitador es el espacio que separa
cada palabra de la siguiente. Mediante el parmetro F (ahora mayscula) se indica
a awk qu carcter debe considerar como separador de campos.

$ awk -F "#" -f primer.awk entrada.txt

Tambin se mostrar la capacidad para usar variables dentro del guin, igual que en
otros lenguajes de programacin. Mediante el parmetro v se puede asignar un valor a
una variable desde la lnea de mandatos:

$ awk v fecha=16/Dic/2001 -f primer.awk entrada.txt

El resto de los parmetros son los nombres de los archivos de datos entrantes. El proceso
se realiza accediendo a los archivos en el orden especificado. Toma el conjunto de los
archivos como si fueran uno solo. Awk espera recibir por la entrada estndar (stdin) los
datos que debe procesar. Por ejemplo:

$ cat ejemplo.txt | awk f primer.awk

Alternativamente, los parmetros indicados al final de la lnea de mandatos se interpretan


como nombres de archivo:
$ awk f primer.awk ejemplo.txt

Suponga el lector que se desea actuar sobre un archivo de texto como el que se muestra a
continuacin. Contiene cuatro lneas de texto terminadas por el carcter de salto de lnea
\n, que no se muestra en la pantalla, salvo por el efecto de escribir en la lnea siguiente:

$ cat ejemplo.txt
La bella y graciosa moza
marchse a lavar la ropa
la frot sobre una piedra
y la colg de un abedul.
$ _

Primeros pasos con awk

Todo el proceso gira en torno a la comparacin de todas las lneas del archivo, ledas una
por una en secuencia, con una o ms plantillas. Cada plantilla contiene una expresin, y
lleva asociada una accin. La sintaxis es, en general, de la forma:

expresin { accin }

Si la evaluacin de la expresin resulta positiva, se realiza la accin asociada. El resultado


de una expresin vaca se considera siempre positivo. Si la accin se omite, se asume que
lo que se desea es mostrar el registro en la salida estndar. Este proceso se reitera con
cada lnea, hasta llegar al final del archivo.

En el siguiente ejemplo se pasa como nico parmetro la plantilla entre comillas simples:

$ cat ejemplo.txt | awk '1'


La bella y graciosa moza
marchse a lavar la ropa
la frot sobre una piedra
y la colg de un abedul.
$ _

Esta plantilla contiene una expresin trivial (1), cuya evaluacin resulta siempre positiva.
En ausencia de una accin asociada explcitamente, awk asume la accin por omisin, que
consiste en mostrar la lnea completa en stdout. Se puede aadir una accin algo ms
sofisticada entre llaves:

$ cat ejemplo.txt | awk '1 { print lnea }'


lnea
lnea
lnea
lnea
$ _

Como puede observarse, la accin print se realiza una vez por cada lnea que se obtiene de
stdin. Para emplear ms de una plantilla se emplea la construccin expresin { accin }
repetidas veces, como en el siguiente ejemplo:

$ cat ejemplo.txt | awk '1 { print lnea } 1 { print recta }'


lnea
recta
lnea
recta
lnea
recta
lnea
recta
$ _

Tambin es posible incorporar varias instrucciones en la misma accin, separadas por el


signo punto y coma:

$ cat ejemplo.txt | awk '1 { print Yo uso; print Linux }'


Yo uso
Linux
Yo uso
Linux
Yo uso
Linux
Yo uso
Linux
$ _

Para no confundir al lector, se omite deliberadamente la mencin de la posibilidad de usar


expresiones regulares semejantes a las que usa "grep". Si el distinguido pblico lector
manifiesta un ferviente deseo de profundizar en el tema, el autor considerar seriamente la
posibilidad de ampliar la informacin al respecto.

Campos de entrada
Para utilizar una expresin que no sea trivial se debe introducir el concepto de campo. Se
considerar cada registro del archivo de entrada como una sucesin de campos delimitados
por un carcter dado. Este carcter es, por omisin, el espacio. Como se ha visto
anteriormente, se puede indicar a awk que considere otro carcter como separador de
campos mediante la opcin F (mayscula) en la lnea de mandatos.

Se hace referencia al contenido de cada campo usando el carcter $ (dlar) seguido del
ordinal del campo: $1, $2, $3, etc. Con la notacin $0 se hace referencia a la lnea entera.

Se puede forzar el proceso del registro carcter a carcter dejando la variable separador
de campos FS sin contenido. De este modo, en $1 se tendr el primer carcter de la lnea,
en $2 el segundo, etc. Incluso en este caso, el campo $0 contendr la lnea completa.

Como quiera que se est anticipando en estos ejemplos el uso de la instruccin "print", se
muestra a continuacin el guin anterior con las modificaciones necesarias para mostrar en
stdout el contenido de la primera y la segunda palabra de cada lnea:

$ cat ejemplo.txt | awk '1 { print Primera y segunda palabras ===>, $1, $2, "<=== final del
registro." }'

Primera y segunda palabras ===> La bella <=== final del registro.


Primera y segunda palabras ===> marchse a <=== final del registro.
Primera y segunda palabras ===> la frot <=== final del registro.
Primera y segunda palabras ===> y la <=== final del registro.
$ _

Se estudiar ms adelante el efecto de la coma en la instruccin "print". Si no se indica otra


cosa, awk inserta un espacio por cada coma que aparezca en esta instruccin.

Variables

Tambin es necesario en este punto citar la existencia de variables predefinidas en el


lenguaje. El concepto tradicional de variable (almacn de datos en memoria,
caracterizado por un nombre no repetido en el mismo contexto y capaz de contener un
dato que puede ser modificado por el programa) se aplica perfectamente en este caso.

El programador puede crear sus propias variables smplemente haciendo referencia a ellas
en expresiones. Las variables pueden ser escalares (con un solo nombre y valor) o
vectoriales (con nombre, subndice y valor) El subndice puede ser una cadena arbitraria, lo
cual permite crear tablas asociativas. Se emplea la notacin nombre[ subndice ] para
referirse a un elemento de la tabla. Tambin se admite la definicin de variables de
naturaleza matricial, con nombre, varios subndices y varios valores, si se usa la notacin
nombre[ subndice1, subndice2, subndice3 ].

Las siguientes variables predefinidas estn relacionadas con la informacin entrante:

FS (Field separator): contiene el carcter que indica a awk en qu punto del registro acaba
un campo y empieza el siguiente. Por omisin es un espacio. Se puede indicar un carcter
alternativo mediante una instruccin de asignacin como FS = /. Si se deja vaco, cada
lectura se realiza dejando un carcter en cada campo.

NF (Number of fields): contiene el nmero total de campos que contiene el registro que se
est leyendo en cada momento.

RS (Record separator): contiene el carcter que indica a awk en qu punto del archivo
acaba un registro y empieza el siguiente. Es \n por omisin.

NR (Number of record): contiene el nmero de orden del registro que se est procesando
en cada momento.

Del mismo modo, se dispone de variables relativas a la informacin de salida, como las
siguientes:

OFS (Output FS): contiene el separador de campos para la salida generada por awk. La
instruccin print inserta en la salida un carcter de separacin cada vez que aparece una
coma en el cdigo. Por ejemplo:

$ echo "manejo un apple" | awk v OFS="\t" 1 {print $1, $2, $3}'

manejo un apple
$ _

ORS (Output RS): Contiene el carcter que awk escribir al final de cada registro. Es \n
por omisin. Obsrvese que en esta modificacin del ejemplo anterior la entrada contiene
DOS registros, dada la aparicin del salto de lnea en el centro de la cadena de caracteres
entre comillas. Al modificar el carcter separador de la salida se genera un solo registro:
$ echo e "manejo un apple\ncaro y elegante" | awk v OFS = "\t" v ORS = \t 1 {print $1, $2, $3}'

manejo un apple caro y elegante


$ _

Operadores

Son aplicables los operadores comunes en C para realizar operaciones aritmticas sobre
variables con valores numricos, y para concatenar los valores contenidos en variables con
valores alfanumricos. As, se tiene:

+ Suma

- Resta

* Multiplicacin

/ Divisin

% Resto

^ Exponenciacin

Esp Concatenacin

Tambin se dispone de los operadores comunes

! Negacin

A ++ Incrementar positivamente en una unidad

A -- Incrementar negativamente en una unidad


A += N Incrementar positivamente en N unidades

A -= N Incrementar negativamente en N unidades

A *= N Multiplicar por N

A /= N Dividir por N

A %= N Reemplazar por el resto de la divisin por N

A ^= N Sinceramente, no s qu demonios hace este operador

> Mayor que

>= Mayor o igual que

< Menor que

<= Menor o igual que

== Igual a

!= Distinto de

?: Formato alternativo de decisin (if/else)

Awk en accin

Para recapitular lo visto hasta ahora, se realizar a continuacin algn proceso sencillo con
el archivo de ejemplo mostrado en prrafos anteriores. El archivo entrante contiene un
nmero tericamente no determinado de registros, terminados por el carcter contenido en
RS. El proceso comienza leyendo el primer registro, aplicando a ste todas las plantillas
existentes con el valor de la variable NR igual a 1. Se reitera el proceso para cada registro,
incrementando en una unidad el valor de NR cada vez.

Cada registro est compuesto por NF campos, delimitados por las apariciones del carcter
FS en el mismo. El ordinal de cada campo se designa, como se indic arriba, con $1, $2,
$3 y as hasta $NF.

Con campos, variables y operadores se puede escribir una plantilla algo ms til que las
anteriores:

$ awk '$5 == moza { print La linea, NR, "contiene MOZA en el quinto campo; }' ejemplo.txt

La lnea 1 contiene MOZA en el quinto campo


$ _

A medida que la lgica de las plantillas se complique, ser de utilidad el parmetro f


(minscula) seguido del nombre del guin o script que contendr las plantillas. Cuando las
plantillas se codifican dentro del script, no se usan las comillas simples para delimitarlas.
Un guin tpico como el que se muestra (proceso.awk en el directorio actual) podra tener
el siguiente contenido:

$ cat proceso.awk

{ print "Procesando la lnea", NR }


NF > 1 { print La lnea tiene ms de una palabra }
$1 == Linux {print La primera palabra es Linux}
$ _

La primera plantilla siempre se ejecuta por no tener expresin delante de las llaves. La
segunda solamente se activa para las lneas que tienen ms de una palabra. La tercera es
aplicable si la lnea comienza con la palabra Linux.

Plantillas de prlogo y eplogo

Dos expresiones especiales, BEGIN y END, permiten realizar acciones antes de procesar el
primer registro, y despus de procesar el ltimo, respectivamente.

El sencillo script suma.awk pone a cero la variable total antes de iniciar el proceso del
archivo de entrada, aade a esa variable el valor correspondiente al contenido del primer
campo de cada registro, y muestra el valor de la variable al final:
$ cat suma.awk

BEGIN { total = 0 }
{ total += $1 }
END { print El total es, total }

Para ejecutarlo, se puede usar lo siguiente (obsrvese que la entrada tiene cuatro
registros):

$ echo -e "10\n10\n10\n70" | awk -f ./suma.awk

El total es 100

Dependiendo de la implementacin de UNIX que se est usando, el script puede fallar si el


campo que interviene en la operacin ($1 en este caso) contiene un valor no numrico. En
este caso se puede forzar la conversin sumando cero a la variable.

Instrucciones de control

Algunas instrucciones del lenguaje C estn presentes en awk de manera simplificada. Se


dispone de la construccin condicional if/else , que se codifica de la manera habitual:

if( expression ) statement [ else statement ]

En algunas implementaciones se puede complicar hasta aadir varias instrucciones


mediante anidamiento de acciones:

{
print Procesando registro, NR;
if( $1 > 0 )
{ print "positivo";
print "El primer campo tiene:", $1;
}
else
{
print "negativo";
}
}

La primera forma de la construccin for se maneja igual que en el lenguaje C, es decir:


for( expression; expression; expression ) statement

donde la primera expresin suele poner valor inicial al ndice. En la segunda se controla
hasta qu momento la ejecucin debe continuar. La tercera marca el nivel de incremento
de la variable ndice.

{
for( i = 0; i < 10; i ++ )
{
j = 2 * i;
print i, j;
}
}

En su segunda forma, la construccin for recorre los elementos de una matriz (array).
Dado el carcter avanzado de este concepto, quedar para un segundo artculo su manejo.

La construccin do/while se emplea en la forma habitual. En el caso actual se realiza un


sencillo contador de cero a diez:

BEGIN { i = 0; do {print i; i ++} while ( i < 10 ) }

La instruccin break permite abandonar un bucle anticipadamente. Para descartar el resto


del cdigo del bucle y empezar una nueva iteracin se usa "continue". La
instruccin next descarta todas las plantillas que siguen, y pasa a realizar el proceso del
siguiente registro. Finalmente, la instruccin nextfile termina anticipadamente el proceso
de un archivo de entrada para pasar al siguiente.

Funciones

Las funciones predefinidas del lenguaje responden al concepto habitual en otros lenguajes
de programacin. La llamada a una funcin se resuelve en tiempo de ejecucin. Cuando se
evala una expresin, se realiza la sustitucin de la llamada a la funcin por el valor que
sta devuelve. Por ejemplo:
$ awk 'BEGIN { print El seno de 30 grados es, sin( 3.141592653589 / 6 ); }' /dev/null

El seno de 30 grados es 0.5


$ _

Se dispone de las funciones matemticas y trigonomtricas exp, log, sqrt, sin, cos y atan2.
Adems, son de mucha utilidad las siguientes:

length( ) Longitud del parmetro en bytes

rand( ) Nmero al azar entre cero y uno

srand( ) Inicia la semilla de generacin al azar

int( ) Devuelve el parmetro convertido en un entero

substr(s,m,n) Devuelve la subcadena de s en m con longitud N

index(s,t) Posicin de s donde aparece t, o cero si no est.

match(s,r) Posicin de s en que se cumple la expresin r.

split(s,a,fs) Devuelve s en elementos separados por fs

sub(r,t,s) Cambia en s la cadena t por r. Es $0 por omisin

gsub(r,t,s) Igual, pero cambia todas las t en la cadena

sprintf(f,e,e) Devuelve cadena de formato f con las e

system(cmd) Ejecuta cmd y devuelve el cdigo de retorno


tolower(s) Devuelve s convertida en minsculas

toupper(s) Devuelve s convertida en maysculas

getline Fuerza una lectura de fichero

La solucin definitiva

El lector avezado debera estar, a estas alturas, preparado para afrontar el desafo del
principio del artculo. Con los mimbres mostrados en las pginas anteriores se tratar de
hacer el cesto deseado. Ser suficiente con que el guin awk resultante sea capaz de
construir un shell script que contenga los mandatos necesarios para autorizar el acceso de
los alumnos al servidor web.

La informacin de partida est contenida en el archivo alumnos.txt, que contiene una


lnea por cada alumno. En esa lnea encontraremos el nombre, los apellidos, la cuenta de
usuario que le corresponde y la contrasea que va a emplear para acceder.

$ cat alumnos.txt
Sebastin Palomo Linares spl18901 jalisco
Pedro Prez Pino ppp0 hatalue
John Jensen jotajota whatafew
Mara del Carmen Garca Feo mc98819 uglymom
$ _

En la salida se desea generar un shell script con el comentario que indica el nombre de la
shell a emplear (#!/bin/bash, por ejemplo) en la primera lnea, y con una lnea
como /usr/bin/htpasswd b usuario contrasea" por cada alumno.

Para poner una pizca de dificultad al problema, pondremos de manifiesto un hecho que
seguramente no extraar al lector; los nombres no tienen un nmero fijo de palabras, y
no se garantiza que todos los alumnos estn expresados con los dos apellidos. As que el
planteamiento simplista que hara un anglosajn no muy despierto, consistente en asociar
$1 con el nombre, $2 con el apellido, $3 con la cuenta y $4 con la contrasea, no conduce
al resultado correcto:

$ awk '{print /usr/bin/htpasswd -b, $3, $4} alumnos.txt

/usr/bin/htpasswd b Linares spl18901


/usr/bin/htpasswd b Pino ppp0
/usr/bin/htpasswd b jotajota whatafew
/usr/bin/htpasswd b Carmen Garca

Otra dificultad que puede presentarse viene dada por la eventual inexistencia de la base de
datos de autorizaciones del servidor web en el momento de la ejecucin del script. A los
efectos de la programacin, implica aadir la opcin -c a la primera llamada al
mandato htpasswd dentro del script que se genera.

La aproximacin correcta al problema consiste en obtener el nmero de campos (palabras)


del registro (lnea), y seleccionar la penltima y la ltima. Afortunadamente, la variable NF
contiene en cada momento el nmero de campos de la lnea que se est procesando. En
este ejemplo puede verse cmo se hace uso de esta capacidad:

$ awk '{ print NF }' alumnos.txt

5
5
4
7

Pero, lo que es realmente maravilloso en este caso es que podemos acceder al valor del
campo que se encuentra en el ltimo lugar con tan solo $NF en lugar de NF:

$ awk '{ print NF, :, $NF }' alumnos.txt

5 : jalisco
5 : hatalue
4 : whatafew
7 : uglymom

Rizando ms el rizo, se puede acceder tambin al penltimo campo empleando una


expresin aritmtica:

$ awk '{ print $(NF - 1) }' alumnos.txt

spl18901
ppp0
jotajota
mc98819

Combinando ambos, es fcil obtener cuenta y contrasea con la instruccin:


$ awk '{ print $(NF - 1), $NF }' alumnos.txt

spl18901 jalisco
ppp0 hatalue
jotajota whatafew
mc98819 uglymom$ _

Para dar los toques finales con ms comodidad se escribira el guin en un archivo llamado
altaweb.awk :

$ cat altaweb.awk

BEGIN { print #!/bin/bash }


{
print /usr/bin/htpasswd,
( NR == 1 ? -c -b : -b ),
$(NF 1), $NF
}
END { print # Shell script generado OK. }
$ _

Puede observarse que se ha usado la sintaxis abreviada de la estructura de


control if/else, tpica del lenguaje C, en la que una expresin antecede al signo de
interrogacin. Al evaluarse positivamente se toma en cuenta el cdigo que aparece antes
del signo de dos puntos. Si la evaluacin es negativa, el cdigo que se ejecuta es el que
sigue a los dos puntos.

La ejecucin del proceso se realiza, como antes, con el mandato que se muestra a
continuacin:

$ awk f altaweb.awk alumnos.txt > altaweb.sh

Solamente resta verificar el contenido del shell script y ejecutarlo. Cuando se tenga
confianza en el resultado se puede obviar el paso intermedio y ejecutar directamente:

$ awk f altaweb.awk alumnos.txt | sh

Conclusin

Awk es un poderoso intrprete, que permite realizar tareas con archivos de tipo secuencial
con una elevada efectividad. La eficacia de su uso en procesos automatizados es innegable,
a la vista de que mi jovial colaborador ha desistido, y se dispone a reinstalar Windows. Sin
embargo, disfrutar de lo lindo con su salvapantallas de tiburones simultaneado con
apariciones espordicas de una misteriosa pantalla azul en la que se glosan las maravillas
de la Excepcin 0E Hasta ms ver.

Ejemplo 1: Una lista personalizada de usuarios


para HTML
Una lnea tpica de /etc/passwd es como la siguiente:

luis:x:504:504:Luis Hernandez:/home/luis:/bin/bash

Bien, supongamos que deseamos un listado de todos los usuarios normales (personas) del
sistema, pero solo necesitamos su nombre de usuario, su nombre o real y su shell por defecto,
es decir, si vemos la lnea anterior, la separacin entre campos es ":" asi que para nuestro
reporte queremos el campo 1,5 y 7. Pero adems, este reporte ser parte de una tabla HTML,
asi que sera bueno si puderian incluirse de una vez las etquietas "<tr> y "<td> necesarias de
una vez. Es decir, el resultado deseado es el siguiente:

<tr><td>luis<td><td>Luis Hernandez</td><td>/bin/bash</td></tr>

El primer paso es determinar los usuarios normales del sistema, podramos usar un grep
"home" /etc/passw | gawk ..., pero podra haber usuarios que tengan su HOME en otra
ubicacin, adems se trata de usar solo awk, asi que lo primero que entenderemos es que los
campos obtenidos del resultado de un comando awk, se numeran por $1, $2, etc. y el
delimitador de campos se indica mediante la variable "FS".

#> gawk '{print $3}' FS=":" /etc/passwd


0
1
2
...
81
86
500
501
502
503
504

Aunque no muy til todava, podemos ver como seleccionamos el caracter separador FS=":",
que viene de 'Field Separator', y tenemos indicada una accin '{print $3}', que significa
imprime el campo 3. Aunque realmente no lo queremos imprimir, lo queremos evaluar, y si
deseamos imprimir el $1, $5 y $7 que se mencionarion previamente, asi que agregamos una
expresin de evaluacin antes de la accin:
#> awk '$3 >= 500 {print $1 $5 $7 }' FS=":" /etc/passwd
sergonSergio Gonzalez/bin/bash
valeriaValeria Perez/bin/bash
fernandaFernanda Lozano/bin/sh
alejandraAlejandra Lopez/bin/nologin
luisLuis Hernandez/bin/bash

Mucho mejor, agregamos '$3 >= 500' previo a la accin (que es imprimir lo que deseamos), ya
que como se sabe en la mayora de distros modernas, los usuarios normales del sistema se
numeran del 500 en adelante (ms sobre administracin de usuarios). Ntese que los campos
en el resultado salen pegados, es necesario agregar entre comillas " ", ya sea un espacio o lo
que se desee, en este caso etiquetas de tablas de HTML y adems ordenaremos "sort" los
registros obtenidos:

#> awk '$3 >= 500 {print "<tr><td>"$1"</td><td>"$5"</td><td>"$7"</td></tr>" | "


sort" }' FS=":" /etc/passwd
<tr><td>alejandra</td><td>Alejandra Lopez</td><td>/bin/nologin</td></tr>
<tr><td>fernanda</td><td>Fernanda Lozano</td><td>/bin/sh</td></tr>
<tr><td>luis</td><td>Luis Hernandez</td><td>/bin/bash</td></tr>
<tr><td>sergon</td><td>Sergio Gonzalez</td><td>/bin/bash</td></tr>
<tr><td>valeria</td><td>Valeria Perez</td><td>/bin/bash</td></tr>

También podría gustarte