Nociones de programación en awk - Arrays
16 - Arrays
Los array permiten el almacenamiento de una serie de elementos que pueden ser accedidos mediante un índice. En realidad los arrays de awk son más potentes que los arrays que vimos cuando estudiamos la programación de la bourne-shell donde los índices de un array eran siempre números enteros. Vamos a usar en primer lugar los arrays de esta forma. Es decir nos vamos a limitar en los primeros ejemplos a usar números enteros como índices.
Vamos a usar awk para procesar la salida obtenida con 'ps'. Primero vamos a suponer que obtenemos un listado completo de los procesos del sistema en formato largo. Si intenta realizar este ejemplo obtendrá un resultado necesariamente diferente.
$ ps axl > ps-axl.out ; cat ps-axl.out FLAGS UID PID PPID PRI NI SIZE RSS WCHAN STA TTY TIME COMMAND 100 0 1 0 0 0 756 0 do_select SW ? 0:03 (init) 40 0 2 1 0 0 0 0 bdflush SW ? 0:18 (kflushd) 40 0 3 1 0 0 0 0 kupdate SW ? 0:18 (kupdate) 840 0 4 1 0 0 0 0 kpiod SW ? 0:00 (kpiod) 840 0 5 1 0 0 0 0 kswapd SW ? 0:15 (kswapd) 140 0 186 1 0 0 900 200 do_select S ? 0:00 /sbin/sys 140 0 188 1 0 0 1016 0 do_syslog SW ? 0:00 (klogd) 140 1 193 1 0 0 780 0 do_select SW ? 0:00 (portmap) 140 0 195 1 0 0 860 0 do_select SW ? 0:00 (inetd) 140 0 200 1 0 0 764 108 nanosleep S ? 0:00 /usr/sbin 140 0 210 1 0 0 908 0 do_select SW ? 0:00 (lpd) 40 31 226 1 0 0 3784 0 do_select SW ? 0:00 (postmast 140 0 237 1 5 0 1728 316 do_select S ? 0:00 sendmail: 140 0 241 1 0 0 1292 184 do_select S ? 0:01 /usr/sbin 40 0 244 1 0 0 1544 56 do_select S ? 0:00 /usr/bin/ 40 1 254 1 0 0 840 96 nanosleep S ? 0:00 /usr/sbin 40 0 257 1 5 0 860 164 nanosleep S ? 0:00 /usr/sbin 140 0 262 1 0 0 1780 60 do_select S ? 0:07 /usr/sbin 100 0 268 1 0 0 1964 616 read_chan S 1 0:00 -bash 100 0 269 1 0 0 836 0 read_chan SW 2 0:00 (getty) 100 1001 270 1 0 0 2096 724 wait4 S 3 0:00 -bash 100 0 271 1 0 0 836 0 read_chan SW 4 0:00 (getty) 100 0 272 1 0 0 836 0 read_chan SW 5 0:00 (getty) 100 1001 273 1 0 0 2088 1408 wait4 S 6 0:00 -bash 140 33 274 262 0 0 1792 0 wait_for_co SW ? 0:00 (apache) 140 33 275 262 0 0 1792 0 flock_lock_ SW ? 0:00 (apache) 140 33 276 262 0 0 1792 0 flock_lock_ SW ? 0:00 (apache) 140 33 277 262 0 0 1792 0 flock_lock_ SW ? 0:00 (apache) 140 33 278 262 0 0 1792 0 flock_lock_ SW ? 0:00 (apache) 0 1001 916 270 0 0 3536 1640 do_select S 3 0:00 vi awk1.d 0 1001 1029 273 0 0 1916 668 wait4 S 6 0:00 xinit /ho 100 0 1034 1029 12 0 8824 3280 do_select S ? 0:02 X :0 -bpp 0 1001 1037 1029 0 0 4620 2748 do_select S 6 0:01 mwm 40 1001 1042 1037 0 0 1728 924 wait4 S 6 0:00 bash /hom 40 1001 1045 1037 0 0 1728 924 wait4 S 6 0:00 bash /hom 0 0 1050 1042 0 0 2976 1872 do_select S 6 0:00 xterm -ls 0 1001 1058 1045 0 0 2320 1220 do_select S 6 0:00 xclock -d 100 1001 1051 1050 14 0 2080 1400 wait4 S p0 0:00 -bash 100000 1001 1074 1051 17 0 1068 528 R p0 0:00 ps axl |
Para dar una idea de la situación de parentescos entre los distintos procesos mostramos la salida obtenida con el comando 'pstree' ejecutado desde la misma sesión de xterm que en el caso anterior.
$ pstree -p > pstree-p.out ; cat pstree-p.out init(1)-+-apache(262)-+-apache(274) | |-apache(275) | |-apache(276) | |-apache(277) | `-apache(278) |-atd(254) |-bash(268) |-bash(270)---vi(916) |-bash(273)---xinit(1029)-+-XF86_S3V(1034) | `-mwm(1037)-+-.xinitrc(1042)---xterm(1050)---bash(1051)---pstree(1068) | `-.xinitrc(1045)---xclock(1058) |-cron(257) |-getty(269) |-getty(271) |-getty(272) |-gpm(200) |-inetd(195) |-kflushd(2) |-klogd(188) |-kpiod(4) |-kswapd(5) |-kupdate(3) |-lpd(210) |-portmap(193) |-postmaster(226) |-sendmail(237) |-sshd(241) |-syslogd(186) `-xfs(244) |
Solo vamos a procesar los campos PID y PPID. $3 y $4 respectivamente. Los meteremos en un par de arrays llamados pid y ppid.
BEGIN { ind=0; }
function padre(p){
for (i=0; i <ind; i++){
if (pid[i]== p)
return ppid[i];
}
}
! /FLAGS/ { pid[ind]=$3 ; ppid[ind]=$4 ; ind++ ; }
END {
do {
printf ("%d->", proc);
proc= padre(proc);
} while ( proc >= 1 )
printf ("\n\n");
}
|
Ahora ejecutamos pasando el pid del proceso del cual deseamos averiguar su descendencia.
| $ awk -f ancestros.awk proc=1051 < ps-axl.out 1051->1050->1042->1037->1029->273->1-> |
Con un número realmente reducido de líneas de código acabamos de procesar la salida de un comando que no estaba especialmente diseñado para ser procesado sino para entregar un resultado legible.
No se emocione todavía porque solo hemos utilizado los arrays con indices numéricos. Lo cierto es que los arrays de 'awk' a diferencia de los arrays de otros lenguajes son arrays asociativos. Eso significa que podemos usar como índice una cadena de caracteres. Por ejemplo podemos hacer lo siguiente: nombre_cli["5143287H"]="Luis, García Toledano"
No es necesario dar un tamaño al array. Un array asociativo no establece un orden entre sus elementos. Hay que aclarar que el manejo de un array con índices numéricos corresponde a un mecanismo muy simple ya que se usan porciones consecutivas de memoria del ordenador y se accede directamente por posición. Por el contrario un array asociativo de las características de 'awk' se va creando dinámicamente. Internamente 'awk' gestiona el acceso mediante una técnica de hash que usa tablas auxiliares a modo de tablas de índices y funciones auxiliares que obtiene valores numéricos a partir de valores de una cadena. Todo ello permite un acceso muy rápido en este tipo de estructuras haciéndolas adecuadas para su uso en bases de datos.
FTLSUSE |CURSOS |FTLinuxCourse para SuSE | 11800 FTLREDH |CURSOS |FTLinuxCourse para RedHat | 11800 ASUSCOM |HARDWARE|Asuscom ISDNLink 128k Adapter (PCI) | 6865 RAILROAD|JUEGOCOM|Railroad Tycoon (Gold Edition) | 7700 CIVILIZ |JUEGOCOM|Civilization: Call to power | 7700 MYTHII |JUEGOCOM|Myth II | 7700 LIAPPDEV|LIBROS |Linux Application Development (537 Páginas) | 11000 CONECT01|LIBROS |Guía del Usuario de Linux (413 Páginas) | 5300 CONECT03|LIBROS |Guía del Servidor (Conectiva Linux 437 Páginas) | 5300 CONECT02|LIBROS |Guía del Administrador de redes (465 Páginas) | 5300 LIUSRESU|LIBROS |Linux User's Resource (795 Páginas) | 12000 RH70DLUX|LINUXCOM|RedHat Linux 7.0 Deluxe en español | 9600 RH70PROF|LINUXCOM|RedHat Linux 7.0 Profesional en Español | 20000 SUSE70 |LINUXCOM|Suse Linux 7.0 (6CDs)(Version española) | 6850 RTIME22 |LINUXCOM|RealTime 2.2 (1CD) | 13000 CONCT50E|LINUXCOM|Conectiva Linux 5.0 Versión Económica Español (6CDs) | 5200 CITIUS22|LINUXCOM|Linux Citius 2.2 | 7750 TRBLIW60|LINUXCOM|Turbolinux Workstation 6.0 | 6500 MOTIF |LINUXCOM|Motif Complete | 22000 CONCTSRV|LINUXCOM|Conectiva Linux Ed.Servidor (Español 3CDs + 4 Manua | 27500 RHORA8I |LINUXCOM|RedHat Linux Enterprise Edition optimized for Oracle8i |270000 MANDRA72|LINUXCOM|Mandrake 7.2 (7CDs) PowerPack Deluxe (versión española| 8300 PINGUINO|SUSEPROM|Pingüino de peluche | 6000
BEGIN {
FS="[\ \t]*\|[\ \t]*" ;
while ( getline < "articulos.dat" > 0) {
artic[$1]= "(" $4 " Ptas + Iva) " $3;
printf ("%s ", $1);
}
for (;;){
printf ("\n\nIntroduzca un código de artículo o solo |
|
Opiniona sobre 'Nociones de programación en awk - Arrays' (2)
Opina sobre este tutorial |

