Recherche récursive du fichier le plus volumineux

41

J'essaie de trouver le fichier le plus volumineux d'un répertoire de manière récursive. S'il y a un sous-répertoire à l'intérieur de ce répertoire, la fonction doit aller à l'intérieur de ce répertoire et vérifier si le fichier le plus volumineux s'y trouve. Une fois que le fichier le plus volumineux est trouvé, le résultat est affiché avec le nom du chemin relatif, ainsi que le nom et la taille du fichier le plus volumineux.

EX:

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

C'est ce que j'ai

#!/bin/sh
clear

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

Je suis coincé depuis un moment maintenant. Je ne peux pas implémenter cela en mettant en pipeline plusieurs outils Unix existants. Toutes les idées seraient bien!

utilisateur2419571
la source
stackoverflow.com/questions/12522269/…
Ciro Santilli a annoncé
aller en seulement subdirs: for d in */ .[^.]*/; faire ... `
Olivier Dulac

Réponses:

54

utilisez find(ici en supposant que GNU find) pour sortir les noms de fichiers avec la taille du fichier. Trier. imprimer le plus grand.

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

Cela suppose que les chemins de fichiers ne contiennent pas de caractères de nouvelle ligne.


Utiliser une boucle bashavec la mise en oeuvre 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"

Ce sera beaucoup plus lent que la solution de recherche. Cela suppose également que les noms de fichiers ne se terminent pas par des caractères de nouvelle ligne, ils ignoreront les fichiers cachés et ne descendront pas dans des répertoires cachés.

Si un fichier est appelé -dans le répertoire en cours, la taille du fichier ouvert sur stdin sera prise en compte.

Attention, les versions bashantérieures à 4.3 suivaient les liens symboliques lors de la descente de l'arborescence.

Glenn Jackman
la source
Merci, ça marche! J'apprécie l'aide. J'essaie de m'habituer à la programmation en shell. Je ne connais pas grand chose en ce moment, alors je vous remercie de me dire ce qui se passe avec cette ligne de code.
user2419571
Question rapide: par curiosité, y a-t-il un moyen de le faire sans commandes de tuyauterie? Je suis curieux parce que tous les exemples que j'ai vus ont utilisé des tuyaux.
user2419571
2
Je suis sûr qu'il y a d'autres façons de le faire. La philosophie UNIX est que les outils doivent avoir un but unique et être chaînés pour que la sortie d'une commande soit introduite dans l'entrée de la suivante.
Glenn Jackman
Ça a du sens. Merci encore pour votre aide.
user2419571
2
@ user2419571:; tail -n 1 <(sort -n <(find . -type f -printf "%s\t%p\n")))
Cyrus le
9

Cette commande permet également d’énumérer la taille définie.

find . -type f -size +100M -exec ls -lh {} \;
sivasamie senthil
la source
5

Cela fonctionne sur BSD / macOS:

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

Vous pouvez également ajouter | head -n 3pour afficher le nombre d'entrées intéressantes (3 dans ce cas).

CeDeROM
la source
1
Cette réponse pourrait être améliorée en expliquant comment cela fonctionne. En outre, cela ressemble beaucoup à la réponse acceptée (ce qui n'explique pas complètement son fonctionnement).
Dhag
man findet man sortutilisez brainz :-)
CeDeROM
Ne fonctionne pas vraiment sur MacOS car il ne parvient pas à retourner correctement la taille et renvoie un grand nombre de colonnes.
sorin
3

Avec zsh, pour le plus gros fichier régulier:

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

(bien sûr, vous pouvez remplacer ls -ld --n'importe quelle commande. Si vous utilisez GNU lsou compatible, voyez aussi l' -hoption pour les tailles lisibles par l'homme )

  • .: uniquement des fichiers normaux (pas des répertoires, des liens symboliques, des périphériques, des fifos ...)
  • D: inclure les cachés et descendre dans des répertoires cachés
  • OL: ordre inverse de la taille ( Length).
  • [1]: seulement le premier match.

S'il y a des liens, vous aurez n'importe lequel d'entre eux au hasard. Si vous voulez le premier dans l’ordre alphabétique, ajoutez un extra on(ordre opar nmotif) pour trier les liens par ordre alphabétique.

Notez qu'il prend en compte la taille des fichiers, pas l'utilisation du disque.

Stéphane Chazelas
la source
... Je commence à croire que vous êtes sur la liste de paie de zsh;) (ce qui pourrait très bien être?). zsh n'est malheureusement pas disponible sur tous les systèmes ...
Olivier Dulac
Possible d'obtenir les dix premiers fichiers? (Sans faire quelque chose de stupide comme une boucle)
Wowfunhappy
1
@Wowfunhappy remplacer [1]par[1,10]
Stéphane Chazelas le