jueves, 3 de agosto de 2017

Accediendo a los elementos de un array

Entonces ¿para qué sirven los arrays? De la misma forma que muchas tareas de gestión de datos pueden realizarse con un programa de hojas de cálculo, muchas tareas de programación pueden realizarse con arrays.

Consideremos un ejemplo simple de recogida y presentación de datos. Construiremos un script que examine la hora de modificación de los archivos de un directorio determinado. A partir de estos datos, nuestro script mostrará una tabla con la hora en que los datos fueron modificados por última vez. Dicho script podría usarse para determinar cuándo está más activo un sistema. Este script, llamado hours, produce este resultado:

[me@linuxbox ~]$ hours .
Hour Files Hour Files
---- ----- ---- -----
00   0     12   11
01   1     13   7
02   0     14   1
03   0     15   7
04   1     16   6
05   1     17   5
06   6     18   4
07   3     19   4
08   1     20   1
09   14    21   0
10   2     22   0
11   5     23   0

Total files = 80

Ejecutamos el programa hours, especificando el directorio actual como objetivo. Produce una tabla mostrando, para cada hora del día (0-23), cuántos archivos han sido modificados por última vez. El código para producir esto es el que sigue:

#!/bin/bash

# hours : script to count files by modification time

usage () {
    echo "usage: $(basename $0) directory" >&2
}

# Check that argument is a directory
if [[ ! -d $1 ]]; then
    usage
    exit 1
fi

# Initialize array
    for i in {0..23}; do hours[i]=0; done

# Collect data
for i in $(stat -c %y "$1"/* | cut -c 12-13); do
    j=${i/#0}
    ((++hours[j]))
    ((++count))
done

# Display data
echo -e "Hour\tFiles\tHour\tFiles"
echo -e "----\t-----\t----\t-----"
for i in {0..11}; do
    j=$((i + 12))
    printf "%02d\t%d\t%02d\t%d\n" $i ${hours[i]} $j ${hours[j]}
done
printf "\nTotal files = %d\n" $count

El script consiste en una función (usage) y un cuerpo principal con cuatro secciones. En la primera sección, comprobamos que hay un argumento en la línea de comandos y que es un directorio. Si no, mostramos el mensaje de uso y salimos.

La segunda sección inicializa el array hours. Lo hace asignando a cada elemento un valor cero. No hay ningún requerimiento especial para preparar arrays antes de usarlos, pero nuestro script necesita asegurarse de que ningún elemento se queda vacío. Fíjate la interesante forma en que el bucle se construye. Empleado expansión con llaves ({0..23}), podemos generar fácilmente una secuencia de palabras para el comando for.

La siguiente sección recoge los datos ejecutando el programa stat en cada archivo del directorio. Usamos cut para extraer los dígitos de la hora del resultado. Dentro del bucle, necesitamos eliminar los ceros a la izquierda de nuestro campo hora, ya que el shell tratará (y finalmente fallará) de interpretar los valores del "00" al "09" como números octales (ver Tabla 34-1). A continuación, incrementamos el valor del elemento del array correspondiente a la hora del día. Finalmente, incrementamos un contador (count) para seguir la pista del número total de archivos en el directorio.

La última sección del script muestra el contenido del array. Primero mostramos un par de líneas de encabezado y luego entramos en un bucle que produce una salida en dos columnas. Finalmente, mostramos el recuento final de los archivos.

No hay comentarios:

Publicar un comentario