Tri récursif des fichiers en fonction de leur taille


80

Je dois trouver les fichiers les plus volumineux d'un dossier.
Comment analyser un dossier de manière récursive et trier le contenu par taille?

J'ai essayé d'utiliser ls -R -S, mais cela répertorie également les répertoires.
J'ai aussi essayé d'utiliser find.


1
Voulez-vous répertorier les fichiers de chaque sous-répertoire séparément ou souhaitez-vous rechercher tous les fichiers de tous les sous-répertoires et les classer par taille, quel que soit leur sous-répertoire? En outre, qu'entendez-vous par "répertoire" et "dossier"? Vous semblez les utiliser pour décrire différentes choses.
terdon

Voulez-vous simplement lister les fichiers d'un répertoire donné ainsi que ceux de ses sous-répertoires sans afficher uniquement les sous-répertoires? S'il vous plaît essayez de nettoyer votre question, ce n'est pas très clair.
slm

Réponses:


93

Vous pouvez également le faire avec juste du. Juste pour être prudent, j'utilise cette version de du:

$ du --version
du (GNU coreutils) 8.5

L'approche:

$ du -ah ..DIR.. | grep -v "/$" | sort -rh

Panne d'approche

La commande du -ah DIRproduira une liste de tous les fichiers et répertoires d'un répertoire donné DIR. La -hvolonté de produire des tailles lisibles par l'homme que je préfère. Si vous ne les voulez pas, alors laissez tomber ce commutateur. J'utilise le head -6juste pour limiter la quantité de sortie!

$ du -ah ~/Downloads/ | head -6
4.4M    /home/saml/Downloads/kodak_W820_wireless_frame/W820_W1020_WirelessFrames_exUG_GLB_en.pdf
624K    /home/saml/Downloads/kodak_W820_wireless_frame/easyshare_w820.pdf
4.9M    /home/saml/Downloads/kodak_W820_wireless_frame/W820_W1020WirelessFrameExUG_GLB_en.pdf
9.8M    /home/saml/Downloads/kodak_W820_wireless_frame
8.0K    /home/saml/Downloads/bugs.xls
604K    /home/saml/Downloads/netgear_gs724t/GS7xxT_HIG_5Jan10.pdf

Assez facile à trier le plus petit au plus grand:

$ du -ah ~/Downloads/ | sort -h | head -6
0   /home/saml/Downloads/apps_archive/monitoring/nagios/nagios-check_sip-1.3/usr/lib64/nagios/plugins/check_ldaps
0   /home/saml/Downloads/data/elasticsearch/nodes/0/indices/logstash-2013.04.06/0/index/write.lock
0   /home/saml/Downloads/data/elasticsearch/nodes/0/indices/logstash-2013.04.06/0/translog/translog-1365292480753
0   /home/saml/Downloads/data/elasticsearch/nodes/0/indices/logstash-2013.04.06/1/index/write.lock
0   /home/saml/Downloads/data/elasticsearch/nodes/0/indices/logstash-2013.04.06/1/translog/translog-1365292480946
0   /home/saml/Downloads/data/elasticsearch/nodes/0/indices/logstash-2013.04.06/2/index/write.lock

Inverser, le plus grand au plus petit:

$ du -ah ~/Downloads/ | sort -rh | head -6
10G /home/saml/Downloads/
3.8G    /home/saml/Downloads/audible/audio_books
3.8G    /home/saml/Downloads/audible
2.3G    /home/saml/Downloads/apps_archive
1.5G    /home/saml/Downloads/digital_blasphemy/db1440ppng.zip
1.5G    /home/saml/Downloads/digital_blasphemy

Ne me montre pas le répertoire, seulement les fichiers:

$ du -ah ~/Downloads/ | grep -v "/$" | sort -rh | head -6 
3.8G    /home/saml/Downloads/audible/audio_books
3.8G    /home/saml/Downloads/audible
2.3G    /home/saml/Downloads/apps_archive
1.5G    /home/saml/Downloads/digital_blasphemy/db1440ppng.zip
1.5G    /home/saml/Downloads/digital_blasphemy
835M    /home/saml/Downloads/apps_archive/cad_cam_cae/salome/Salome-V6_5_0-LGPL-x86_64.run

Si vous voulez juste la liste du plus petit au plus grand, mais les 6 principaux fichiers choquants, vous pouvez inverser le commutateur de tri, déposer ( -r) et utiliser à la tail -6place du fichier head -6.

$ du -ah ~/Downloads/ | grep -v "/$" | sort -h | tail -6
835M    /home/saml/Downloads/apps_archive/cad_cam_cae/salome/Salome-V6_5_0-LGPL-x86_64.run
1.5G    /home/saml/Downloads/digital_blasphemy
1.5G    /home/saml/Downloads/digital_blasphemy/db1440ppng.zip
2.3G    /home/saml/Downloads/apps_archive
3.8G    /home/saml/Downloads/audible
3.8G    /home/saml/Downloads/audible/audio_books

14
La grep -v "/$"partie ne semble pas faire ce que vous attendiez, car les répertoires n'ont pas de barre oblique ajoutée. Est-ce que quelqu'un sait comment exclure les répertoires des résultats?
Jan Warchoł

@ JanekWarchol - quelle version de coreutils utilisez-vous?
slm

Je suis sur 8.13. Quoi qu'il en soit, le résultat de votre réponse ne comporte pas de fin de /texte non plus - par exemple, il /home/saml/Downloads/audiblesemble que ce soit un répertoire, mais il ne comporte pas de barre oblique. Il n'y /home/saml/Downloads/a qu'une barre oblique, mais c'est probablement parce que vous l'avez écrit avec une barre oblique lorsque vous spécifiez l'argument pour l'initiale du.
Jan Warchoł

1
This trouve dirs aussi
ekerner

1
Cela ne liste pas seulement les fichiers, mais aussi les répertoires :(
Roman Gaufman

21

Si vous souhaitez rechercher tous les fichiers du répertoire en cours et de ses sous-répertoires et les répertorier en fonction de leur taille (sans tenir compte de leur chemin), et en supposant qu'aucun des noms de fichiers ne contient de caractères de nouvelle ligne, avec GNU find, procédez comme suit:

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

Depuis man findun système GNU:

   -printf format
          True; print format  on  the  standard  output,
          interpreting  `\'  escapes and `%' directives.
          Field widths and precisions can  be  specified
          as  with the `printf' C function.  Please note
          that many of the  fields  are  printed  as  %s
          rather  than  %d, and this may mean that flags
          don't work as you  might  expect.   This  also
          means  that  the `-' flag does work (it forces
          fields to be  left-aligned).   Unlike  -print,
          -printf  does  not add a newline at the end of
          the string.  The escapes and directives are:

          %p     File's name.
          %s     File's size in bytes.

De man sort:

   -n, --numeric-sort
          compare according to string numerical value

Ne fonctionne pas sur Mac malheureusement, montre: trouver: -printf: principal ou opérateur inconnu
Roman Gaufman le

@RomanGaufman oui, c'est pourquoi la réponse spécifie la recherche GNU . Si vous installez les outils GNU sur votre Mac, cela fonctionnera également là-bas.
terdon

11

Essayez la commande suivante:

ls -1Rhs | sed -e "s/^ *//" | grep "^[0-9]" | sort -hr | head -n20

Il listera récursivement les 20 plus gros fichiers du répertoire en cours.

Remarque: L’option -hfor sortn’est pas disponible sous OSX / BSD. Vous devez donc installer à sortpartir de coreutils(par ex. Via brew) et appliquer le chemin du bac local à PATH, par ex.

export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" # Add a "gnubin" for coreutils.

Vous pouvez également utiliser:

ls -1Rs | sed -e "s/^ *//" | grep "^[0-9]" | sort -nr | head -n20

Pour les plus grands annuaires du, par exemple:

du -ah . | sort -rh | head -20

ou:

du -a . | sort -rn | head -20

3
Parfait, c'est la première solution qui fonctionne sur Mac et ne montre pas de répertoires :) - merci!
Roman Gaufman

comment filtrer pour afficher uniquement les fichiers avec un nombre de lignes> = X? (X = 0 par exemple)
Matrix

7

Tous les fichiers seront récursivement et triés par taille. Il imprime toutes les tailles de fichier en ko et arrondit à la baisse pour que vous puissiez voir des fichiers de 0 ko, mais il était assez proche pour mes utilisations et fonctionne sur OSX.

find . -type f -print0 | xargs -0 ls -la | awk '{print int($5/1000) " KB\t" $9}' | sort -n -r -k1


travaillé sur Ubuntu 14.04 aussi!
David Lam

Cela répertorie les répertoires, pas seulement les fichiers :(
Roman Gaufman

@RomanGaufman - merci pour les commentaires! à partir de mes tests, find . -type ftrouve des fichiers ... cela fonctionne de manière récursive, vous avez raison, mais il répertorie tous les fichiers qu'il trouve, pas les répertoires eux
Brad Parks

Xargs a été utilisé dans les années 1980. C'est une mauvaise idée depuis 1989, lorsque David Korn a présenté execplus.
Schily

5

Avec zsh, vous trouveriez le fichier le plus volumineux (en termes de taille apparente, telle que la colonne de taille dans la ls -lsortie, pas d'utilisation du disque) avec:

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

Pour les 6 plus grands:

ls -ld -- **/*(DOL[1,6])

Pour les trier par taille de fichier, vous pouvez utiliser lsl' -Soption de. Certaines lsimplémentations ont également une -Uoption pour lsne pas trier la liste (comme elle est déjà triée par taille zshici).


3

Solution simple pour Mac / Linux qui ignore les répertoires:

find . -type f -exec du -h {} \; | sort -h

2

L'équivalent en BSDou OSXest

$ du -ah simpl | sort -dr | head -6

0

C’est un besoin extrêmement commun pour diverses raisons (j’aime bien trouver la sauvegarde la plus récente dans un répertoire) et c’est une tâche étonnamment simple.

Je vais fournir une solution Linux qui utilise les utilitaires find, xargs, stat, tail, awk et sort.

La plupart des gens ont fourni des réponses uniques, mais je préfère la mienne car elle gère correctement les noms de fichiers et que le cas d'utilisation peut facilement être modifié (modification de stat et tri des arguments).

Je fournirai également une solution Python qui devrait vous permettre d'utiliser cette fonctionnalité même sous Windows.

Solution de ligne de commande Linux

Renvoyer récursivement la liste complète des fichiers d'un répertoire uniquement, triés par taille

find . -type f -print0 | xargs -0 -I{} stat -c '%s %n' {} | sort -n

Comme auparavant, mais cette fois, renvoyez le fichier le plus volumineux.

# Each utility is split on a new line to help 
# visualize the concept of transforming our data in a stream
find . -type f -print0 | 
xargs -0 -I{} stat -c '%s %n' {} | 
sort -n | 
tail -n 1 |
awk '{print $2}'

Même motif exact, mais sélectionnez maintenant le fichier le plus récent au lieu du plus gros

# (Notice only the first argument of stat changed for new functionality!)
find . -type f -print0 | xargs -0 -I{} stat -c '%Y %n' {} | 
sort -n | tail -n 1 | awk '{print $2}'

Explication:

  1. find: recherche récursivement tous les fichiers du répertoire en cours et les affiche avec un caractère nul
  2. xargs: utilitaire permettant d'exécuter des commandes à l'aide d'arguments fournis à partir d'une entrée standard. Pour chaque ligne de sortie, nous voulons exécuter l'utilitaire stat sur ce fichier.
  3. stat: Stat est une commande géniale qui a tellement de cas d'utilisation. J'imprime deux colonnes, la première colonne étant la taille du bloc (% s) et la deuxième colonne le nom du fichier (% n)
  4. sort: Triez les résultats avec le commutateur numérique. Comme le premier argument est un entier, nos résultats seront triés correctement
  5. tail: sélectionne uniquement la dernière ligne de sortie (puisque la liste est triée, c'est le fichier le plus volumineux!)
  6. awk: Sélectionnez la deuxième colonne, qui contient le nom du fichier et qui est le fichier le plus volumineux d'un répertoire récursif.

Solution python

#!/usr/bin/env python
import os, sys
files = list()
for dirpath, dirname, filenames in os.walk(sys.argv[1]):
    for filename in filenames:
        realpath = os.path.join(dirpath, filename)
        files.append(realpath)
files_sorted_by_size = sorted(files, key = lambda x: os.stat(x).st_size)
largest_file = files_sorted_by_size[-1]
print(largest_file)

Ce script prend un peu plus de temps à expliquer, mais si vous enregistrez ce script sous forme de script, il effectuera une recherche dans le premier argument fourni sur la ligne de commande et renverra le fichier le plus volumineux de ce répertoire. Le script ne vérifie pas les erreurs, mais il devrait vous donner une idée de la façon de l'aborder en Python, ce qui vous donne un moyen agréable de résoudre ce problème indépendamment de la plate-forme.



0

Essayez ci-dessous commande avec option de tri pour avoir des dossiers avec la taille dans l'ordre croissant

du -sh * | sort -sh


-1

Quelque chose qui fonctionne sur toutes les plates-formes sauf AIX et HP-UX est:

find . -ls | sort +6 | tail
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.