El resultado incluiría el nombre del directorio, el nombre del archivo y el tamaño del archivo. Uno (archivo más grande) para cada directorio desde donde se ejecuta el comando.
Si es posible, también el tamaño promedio de los archivos en ese directorio.
El propósito es buscar en los directorios archivos que sean mucho más grandes que los demás en el directorio para poder reemplazarlos.
Respuesta1
Con GNU find
y sort
( sed
4.2.2 o superior), ordene una vez por tamaño de archivo y otra vez por ruta de directorio:
find /some/dir -type f -printf '%s %f%h\0' |
sort -zrn |
sort -zut/ -k2 |
sed -zre 's: ([^/]*)(/.*): \2/\1:'
Explicación:
- Se imprimen el tamaño del archivo, el nombre y la ruta (el primero separado por un espacio y los dos siguientes separados por
/
), y cada entrada termina con el carácter ASCII NUL. - Luego ordenamos numéricamente usando el tamaño, asumiendo una salida delimitada por NUL (y en orden inverso, por lo que los archivos más grandes primero).
- Luego usamos
sort
para imprimir solo las primeras entradas únicas usando todo lo del segundo/
campo separado, que sería la ruta al directorio que contiene el archivo. - Luego usamos
sed
para intercambiar el directorio y los nombres de archivos, de modo que obtengamos una ruta normal.
Para obtener resultados legibles, reemplace ASCII NUL con nuevas líneas:
find /some/dir -type f -printf '%s %f%h\0' |
sort -zrn |
sort -zut/ -k2 |
sed -zre 's: ([^/]*)(/.*): \2/\1:' |
tr '\0' '\n'
Salida de ejemplo:
$ find /var/log -type f -printf '%s %f%h\0' | sort -zrn | sort -zt/ -uk2 | sed -zre 's: ([^/]*)(/.*): \2/\1:' | tr '\0' '\n'
3090885 /var/log/syslog.1
39789 /var/log/apt/term.log
3968 /var/log/cups/access_log.1
31 /var/log/fsck/checkroot
467020 /var/log/installer/initial-status.gz
44636 /var/log/lightdm/seat0-greeter.log
15149 /var/log/lxd/lxd.log
4932 /var/log/snort/snort.log
3232 /var/log/unattended-upgrades/unattended-upgrades-dpkg.log
Respuesta2
Combinando find
y awk
permite calcular también los promedios:
find . -type f -printf '%s %h/%f\0'|awk 'BEGIN { RS="\0" } { SIZE=$1; for (i = 1; i <= NF - 1; i++) $i = $(i + 1); NF = NF - 1; DIR=$0; gsub("/[^/]+$", "", DIR); FILE=substr($0, length(DIR) + 2); SUMSIZES[DIR] += SIZE; NBFILES[DIR]++; if (SIZE > MAXSIZE[DIR] || !BIGGESTFILE[DIR]) { MAXSIZE[DIR] = SIZE; BIGGESTFILE[DIR] = FILE } }; END { for (DIR in SUMSIZES) { printf "%s: average %f, biggest file %s %d\n", DIR, SUMSIZES[DIR] / NBFILES[DIR], BIGGESTFILE[DIR], MAXSIZE[DIR] } }'
Presentado de una manera más legible, el script AWK es
BEGIN { RS="\0" }
{
SIZE=$1
for (i = 1; i <= NF - 1; i++) $i = $(i + 1)
NF = NF - 1
DIR=$0
gsub("/[^/]+$", "", DIR)
FILE=substr($0, length(DIR) + 2)
SUMSIZES[DIR] += SIZE
NBFILES[DIR]++
if (SIZE > MAXSIZE[DIR] || !BIGGESTFILE[DIR]) {
MAXSIZE[DIR] = SIZE
BIGGESTFILE[DIR] = FILE
}
}
END {
for (DIR in SUMSIZES) {
printf "%s: average %f, biggest file %s %d\n", DIR, SUMSIZES[DIR] / NBFILES[DIR], BIGGESTFILE[DIR], MAXSIZE[DIR]
}
}
Esto espera registros de entrada separados por nulos (lo robé dela respuesta de muru); para cada registro de entrada,
- almacena el tamaño (para uso posterior),
- elimina todo lo que está antes del primer carácter en la ruta (para que al menos manejemos correctamente los nombres de archivos con espacios),
- extrae el directorio,
- extrae el nombre del archivo,
- agrega el tamaño que almacenamos anteriormente a la suma de tamaños en el directorio,
- incrementa el número de archivos en el directorio (para que podamos calcular el promedio),
- si el tamaño es mayor que el tamaño máximo almacenado para el directorio, o si aún no hemos visto un archivo en el directorio, actualiza la información del archivo más grande.
Una vez hecho todo esto, el script recorre las claves SUMSIZES
y genera el directorio, el tamaño promedio, el nombre y el tamaño del archivo más grande.
Puede canalizar la salida sort
para ordenarla por nombre de directorio. Si desea formatear adicionalmente los tamaños en una forma amigable para los humanos, puede cambiar la printf
línea a
printf "%.2f %d %s: %s\n", SUMSIZES[DIR] / NBFILES[DIR], MAXSIZE[DIR], DIR, BIGGESTFILE[DIR]
y luego canalice la salida a numfmt --field=1,2 --to=iec
. Aún puedes ordenar el resultado por nombre de directorio, solo necesitas ordenar comenzando con el tercer campo: sort -k3
.
Respuesta3
Zsh'spatrones comodínSería muy útil para el tipo de cosas que estás haciendo. Específicamente, zsh puede hacer coincidir archivos por atributos como tipo, tamaño, etc. a través declasificatorios globales. Los clasificatorios globales también permiten ordenar los partidos.
Por ejemplo, en zsh, *(.DOLN[1])
se expande al nombre del archivo más grande en el directorio actual. *
es el patrón para el nombre del archivo (coincide con todo, excepto posiblemente con archivos de puntos dependiendo de las opciones del shell). El calificador .
restringe las coincidencias a archivos normales, D
hace que *
se incluyan archivos de puntos, OL
ordena por tamaño decreciente (“longitud”), N
hace que la expansión esté vacía si no hay ningún archivo coincidente y [1]
selecciona solo la primera coincidencia.
Puede enumerar directorios de forma recursiva con **/
. Por ejemplo, el siguiente bucle itera sobre todos los subdirectorios del directorio actual y sus subdirectorios de forma recursiva:
for d in **/*(/); do … done
Puedes usarzstat
para acceder al tamaño de un archivo y otros metadatos sin tener que depender de otras herramientas para el análisis.
zmodload -F zsh/stat b:zstat
files=(*(DNoL))
zstat -A sizes +size -- $files
total=0; for s in $sizes; do total+=$s; done
if ((#sizes > 0)); then
max=$sizes[-1]
average=$((total/#sizes))
median=$sizes[$((#sizes/2))]
fi
Respuesta4
Considere el uso de baobab o algún software similar, y es probable que uno o más de ellos estén incluidos en su distribución. Visualizan muy bien los directorios de problemas.
- Baobab
- Informe JDisk
- ncdu
- K4DirStat
- QDirEstat
- Mapa de GD
http://alternativeto.net/software/baobab/?platform=linux
Y la página de manual de baobab dice cómo es.
$> man baobab
BAOBAB(1)
NAME
Baobab - A graphical tool to analyse disk usage
SYNOPSIS
baobab [directory]
DESCRIPTION
baobab is able to scan either specific folders or the whole filesys-
tem (local and remote), in order to give the user a graphical tree
representation including each directory size or percentage in the
branch. It also auto-detects in real-time any change made to your
home directory as far as any mounted/unmounted device. A graphical
treemap window is also provided for any selected folder.
A detailed documentation on the program could be read at:
http://www.gnome.org/projects/baobab
AUTHOR
Fabio MARZOCCA <[email protected]>
BAOBAB(1)