Encontrar el archivo más grande de forma recursiva


41

Estoy tratando de encontrar el archivo más grande en un directorio de forma recursiva. Si hay un subdirectorio dentro de ese directorio, la función debe ir dentro de ese directorio y verificar si el archivo más grande está allí. Una vez que se encuentra el archivo más grande, la salida se muestra con el nombre de la ruta relativa y el nombre y el tamaño del archivo más grande.

EX:

dude@shell2 (~...assignment/solutions) % bash maxfile.sh ~/test
class/asn
dude.h.gch: 9481628

Esto es lo que tengo:

#!/bin/sh
clear

recursiveS() {
    for d in *; do
        if [ -d $d ]; then
            (cd $d; echo $(pwd)/$line; du -a; recursiveS;)
        fi
    done
}
recursiveS

He estado atrapado por un tiempo ahora. No puedo implementar esto al canalizar una serie de herramientas Unix existentes. Cualquier idea sería buena!



ir en sólo subdirectorios: for d in */ .[^.]*/; do ... `
Olivier Dulac

Respuestas:


54

use find(aquí suponiendo GNU find) para generar nombres de archivo con el tamaño del archivo. ordenar. imprime el más grande.

find . -type f -printf "%s\t%p\n" | sort -n | tail -1

Eso supone que las rutas de los archivos no contienen caracteres de nueva línea.


Usando un bucle bashcon la implementación de GNU de stat:

shopt -s globstar
max_s=0
for f in **; do
  if [[ -f "$f" && ! -L "$f" ]]; then
    size=$( stat -c %s -- "$f" )
    if (( size > max_s )); then
      max_s=$size
      max_f=$f
    fi
  fi
done
echo "$max_s $max_f"

Esto será significativamente más lento que la solución de búsqueda. Eso también supone que los nombres de archivo no terminan en caracteres de nueva línea y omitirán los archivos ocultos y no descenderán a directorios ocultos.

Si hay un archivo llamado -en el directorio actual, se considerará el tamaño del archivo abierto en stdin.

Tenga en cuenta que las versiones bashanteriores a 4.3 seguían enlaces simbólicos al descender el árbol de directorios.


Gracias, funciona! Agradezco la ayuda. Estoy tratando de acostumbrarme a la programación en shell. No sé mucho en este momento, así que agradezco que me digas lo que está sucediendo con esa línea de código.
user2419571

Pregunta rápida: Por curiosidad, ¿hay alguna manera de hacerlo sin comandos de canalización? Tengo curiosidad porque cada ejemplo que he visto ha utilizado tuberías de algún tipo.
user2419571

2
Estoy seguro de que hay otras formas de hacerlo. La filosofía de UNIX es que las herramientas deben ser de un solo propósito y encadenarlas para que la salida de un comando se alimente a la entrada del siguiente.
Glenn Jackman

Eso tiene sentido. Gracias de nuevo por tu ayuda.
user2419571

2
@ user2419571:; tail -n 1 <(sort -n <(find . -type f -printf "%s\t%p\n")))
Cyrus

9

Este comando también ayuda a enumerar el tamaño definido.

find . -type f -size +100M -exec ls -lh {} \;

5

Esto funciona en BSD / macOS:

find . -type f -ls | sort -k7 -r

También puede adjuntar | head -n 3para mostrar el número de entradas interesantes (3 en este caso).


1
Esta respuesta podría mejorarse explicando cómo funciona. Además, se ve muy similar a la respuesta aceptada (que tampoco explica completamente cómo funciona).
dhag

man findy man sort, use brainz :-)
CeDeROM

Realmente no funciona en MacOS, ya que no puede devolver el tamaño correctamente y devuelve una gran cantidad de columnas.
sorin

3

Con zsh, para el archivo regular más grande:

ls -ld -- **/*(.DOL[1])

(por supuesto, puede reemplazarlo ls -ld --con cualquier comando. Si usa GNU lso compatible, consulte también la -hopción para tamaños legibles por humanos )

  • .: solo archivos normales (no directorios, enlaces simbólicos, dispositivos, fifos ...)
  • D: incluye los ocultos y desciende a directorios ocultos
  • OL: orden inverso por tamaño ( Length).
  • [1]: solo el primer partido.

Si hay empates, obtendrás cualquiera de ellos al azar. Si desea el primero en orden alfabético, agregue un extra on( order by name) para ordenar los lazos alfabéticamente.

Tenga en cuenta que considera el tamaño de los archivos, no el uso del disco.


... Empiezo a creer que estás en la nómina de zsh;) (¿cuál podría ser?). Desafortunadamente, zsh no está disponible en todos los sistemas ...
Olivier Dulac

¿Posible obtener los primeros diez archivos? (Sin hacer algo estúpido como un bucle)
Wowfunhappy

1
@Wowfunhappy reemplazar [1]con[1,10]
Stéphane Chazelas
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.