Blog ElCodiguero
12 Nov 2014 Linux & UNIX

Calcular el tamaño total de una lista de archivos

En la línea de comandos de UNIX o Linux es muy sencillo conocer el tamaño de un archivo en particular, usando ls -l, stat, o du -s:

$ ls -l archivo_prueba
-rw-r--r-- 1 alvaro users 438496 nov 12 21:37 archivo_prueba

$ stat -c %s archivo_prueba
438496

$ du -sh archivo_prueba
432K    archivo_prueba

También es sencillo obtener el espacio usado por un directorio, basta con usar du directorio.

Para obtener el espacio ocupado por un grupo de archivos, si tenemos GNU du (incluído en los sistemas Linux), disponemos de la opción -c, que indica a du que debe escribir el espacio total ocupado por los archivos o directorios pasados como argumento:

~$ du -hc *
12K     archivo1
8,0K    archivo2
88K     archivo3
108K    total

Siguiendo las mejores tradiciones de UNIX (incompatibilidades entre sistemas, diferentes opciones para el mismo programa), nos encontramos con que du no tiene la opción -c en Solaris, por ejemplo. Veamos cómo podemos solucionar el problema.

Opción 1: AWK

Como vimos arriba, hay (por lo menos) tres maneras diferentes de obtener el tamaño de un archivo, cada una con sus propios problemas:

Solamente como ejercicio, intentemos replicar lo que nos brinda la opción -c de du. Lo podemos hacer fácilmente sumando la primer columna de la salida de du, en un programa de awk como el siguiente:

du -k archivo* | awk '
    BEGIN {
        suma=0
    }
    {
        print; # imprimir línea, tal y como lo hace du
        suma += $1; # calculamos la suma parcial
    }
    END {
        print suma " total";
    }
'

Este programa inicializa la variable suma en el bloque BEGIN (que se ejecuta antes de comenzar a leer la entrada). Luego, para cada línea de su entrada (la salida de du), imprime la línea y agrega el tamaño del archivo al que pertenece esa línea a la variable suma. Luego de hacer esto para cada línea devuelta por du, ejecuta el bloque END, que consiste en imprimir la suma total. Este es un programa típico de awk para hacer cálculos con valores leídos de un archivo.

Opción 2: Bash/ksh puro

Si la opción de awk no te sirve, por el motivo que sea, la shell puede hacer el mismo cálculo con un simple bloque while:

SUMA=0
while read LINEA
do
    echo $LINEA
    SUMA=$(( SUMA + $(echo $LINEA | cut -d" " -f 1) ))
done
echo $SUMA total

Guarda el código anterior en un script, y luego llámalo como

du -k archivo* | ./script.sh

Opción 3: Perl

Las opciones anteriores deberían funcionar en cualquier sistema, pero como tenía este código guardado por ahí desde hace varios años, pensé en publicarlo también. El siguiente programa en Perl calcula el tamaño total de los archivos que se le pasan como argumentos, y ofrece una salida similar a la que buscamos:

#!/usr/bin/env perl

my $tamanio_total = 0;
my $tamanio = 0;

foreach (@ARGV) {
    $tamanio = -s $_;
    print "$tamanio\t$_\n";
    $tamanio_total += $tamanio;
}
print "$tamanio_total\ttotal\n";

La parte más importante de este script es el uso de -s para obtener el tamaño de cada archivo.

Otras variantes

Como siempre que programamos, hay otras formas de hacer este cálculo y de manipular los datos como queramos (por ejemplo, dividir entre 1024 para obtener MB de KB). Creo, sin embargo, que con las cuatro maneras descriptas, estamos más que cubiertos para cualquier situación que podamos encontrar.

Activa Javascript para para cargar los comentarios, basados en DISQUS

El Blog de ElCodiguero funciona sobre Pelican

Inicio | Blog | Acerca de