Liste des fichiers dans un répertoire, y compris le contenu des sous-dossiers avec tri

9

Je cherche à lister l'intégralité du contenu d'un répertoire, y compris le contenu des sous-dossiers, mais trié par taille de fichier. Jusqu'à présent, j'ai réussi à lister et à trier tout en étant récursif ls -lhSR( hc'est bien d'avoir mais certainement pas essentiel pour moi, tant que je peux obtenir des tailles de fichier). Je néglige probablement quelque chose d'évident ou demande l'impossible, mais tout conseil ici serait grandement apprécié.

toms
la source

Réponses:

15

Vous pouvez utiliser find:

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

Facultatif: pour convertir les valeurs d'octets en un format lisible par l'homme, ajoutez ceci:

| numfmt --to=iec-i --field=1

Explication:

 find in current directory (.) all files (-type f) 

 -printf: suppress normal output and print the following:
     %s - size in bytes
     %P - path to file
     \n - new line

 | sort -n: sort the result (-n = numeric)
pLumo
la source
Oh parfait! Merci beaucoup, cela a fait exactement ce dont j'avais besoin!
toms
3
Je suis content que ma réponse vous ait aidé. Veuillez envisager de cliquer sur la coche sur le côté gauche pour marquer la réponse comme acceptée. Merci.
pLumo
1
@RoVo, il serait également intéressant de voter positivement car, étant donné que vous y avez répondu, vous l'avez probablement trouvée intéressante et utile.
terdon
C'est en effet vrai et je l'ai fait maintenant ;-)
pLumo
@toms C'est OK d'attendre un moment (peut-être un jour ou deux) pour accepter la réponse, même quand elle est aussi bonne que celle-ci. Une fois la réponse acceptée, il n'y a aucun moyen qu'une autre réponse se révèle encore meilleure. Et à cause de cela, beaucoup de gens ne prendront pas la peine de soumettre d'autres réponses, donc nous n'avons pas la chance de les voir pour savoir si c'est mieux.
Monty Harder
7

Puisque vous n'avez pas spécifié de shell particulier, voici une alternative en utilisant les qualificatifs glob de zsh avec

setopt extendedglob

pour la récursivité. Alors par exemple:

  1. liste récursivement les fichiers simples:

    printf '%s\n' **/*(.)
  2. la liste récursive des fichiers simples, o rdered par au froissement L ONGUEUR (taille -à- dire):

    printf '%s\n' **/*(.oL)
  3. liste récursive fichiers simples, O rdered par de la taille de rainage:

    printf '%s\n' **/*(.OL)
  4. lister récursivement les fichiers ordinaires, classés par taille décroissante, et sélectionner les 3 premiers résultats:

    printf '%s\n' **/*(.OL[1,3])

Si vous souhaitez également les tailles de fichier, vous pouvez utiliser

du -hb **/*(.OL[1,3])
tournevis
la source
4

Avec le globstarjeu d'options shell, vous pouvez utiliser la globalisation du shell:

shopt -s globstar         # don’t match hidden files
shopt -s globstar dotglob # match hidden files
stat -c"%s %n" **/* | sort -n

Si vous essayez cela avec trop de fichiers, vous obtiendrez une erreur «Liste d'arguments trop longue». Pour contourner cela, vous pouvez utiliser printfet xargs:

printf "%s\0" **/* | xargs -0 stat -c"%s %n" | sort -n

Je viens de réaliser que cela affiche également les répertoires (avec une taille de 4096 octets) - si vous ne le souhaitez pas, utilisez-le à la place:

stat -c"%A %s %n" **/* | sed '/^d/d;s/\S* //' | sort -n
printf "%s\0" **/* | xargs -0 stat -c"%A %s %n" | sed '/^d/d;s/\S* //' | sort -n

Exemple d'exécution

$ tree
.
├── edits.png
├── makescript
├── new
   └── edits.png
└── test
    └── 1.png

2 directories, 4 files
$ stat -c"%s %n" **/* | sort -n
0 test/1.png
43 makescript
2160 edits.png
2160 new/edits.png
4096 new
4096 test
$ stat -c"%A %s %n" **/* | sed '/^d/d;s/\S* //' | sort -n
0 test/1.png
43 makescript
2160 edits.png
2160 new/edits.png
dessert
la source
Belle solution. Comparé à trouver, il n'inclut pas de fichiers cachés, comment y parvenir?
pLumo
@RoVo Oubliez toujours ces derniers - il vous suffit de définir l' dotgloboption shell, voir ma réponse mise à jour.
dessert
Au lieu de supprimer les répertoires après coup avec sed, vous pourriez envisager quelque chose commeprintf "%s\0" **/* | xargs -0 sh -c 'for f; do [ -d "$f" ] || stat -c "%s %n" "$f"; done' sh | sort -n
steeldriver
Vous pouvez l'utiliser ls -lhSd **/*si cela ne vous dérange pas d'avoir les répertoires dans la liste. Ou si aucun de vos noms de répertoire ne .s'y trouve, et que tous les fichiers que vous voulez faire , vous pouvez ll -hS **/*.*, ou similaire.
Peter Cordes
transformé cela en une réponse
Peter Cordes
3

Si vous n'avez pas zsh, vous pouvez toujours utiliser du+ sort:

  1. Tailles lisibles par l'homme, y compris les tailles cumulatives des répertoires:

    du --apparent-size -ah0 . | sort -zh | xargs -0L1
    
  2. Seuls les fichiers (en utilisant find):

    find . -type f -print0 |
      du --files0-from=- --apparent-size -ah0 |
      sort -zh |
      xargs -0L1
    

Dans les deux cas, j'ai choisi d'utiliser des lignes terminées par null ( -0, -z, -print0options), pour être sûr contre tous les noms de fichiers valides.

muru
la source
0

Pour une utilisation interactive rapide sur des arborescences de répertoires qui ne sont pas trop énormes, shopt -s globstarc'est vraiment sympa. Un glob ne peut pas filtrer les répertoires en fonction du type, mais si vous l'utilisez avec ls -dalors il lsaffichera simplement le nom du répertoire, au lieu du contenu.

En supposant que votre llalias comprend -lh:

  # with  shopt -s globstar   in your .bashrc
ll -rSd **/*

vous donnera une sortie comme celle-ci (à partir de mon répertoire code-golf), mais avec des couleurs en surbrillance (il est donc plus facile de voir les répertoires). Notez que le tri par taille de fichier s'est produit dans les sous-répertoires.

drwxr-xr-x 1 peter peter   70 Jun  8 07:56 casexchg
...
drwxr-xr-x 1 peter peter  342 Mar 13 18:47 parity-party
-rw-r--r-- 1 peter peter  387 Jul 29  2017 likely.cpp
-rw-r--r-- 1 peter peter  416 Aug 31  2017 true-binary.asm~
-rw-r--r-- 1 peter peter  447 Feb 23 20:14 weight-of-zero.asm
...
-rw-r--r-- 1 peter peter 6.4K Jun  1  2017 string-exponential.asm
-rwxr-xr-x 1 peter peter 6.7K Aug 31  2017 true-binary
-rwxr-xr-x 1 peter peter 6.8K Sep 17  2017 dizzy-integer
-rw-r--r-- 1 peter peter 7.5K Jul 24  2017 fibonacci/fibonacci-1G.v3-working-32b-stack-except-output.asm
-rw-r--r-- 1 peter peter 8.4K Jul 25  2017 fibonacci/perf.32bit-pop-114limb.sub-cmc.1G~
-rw-r--r-- 1 peter peter 8.4K Jul 25  2017 fibonacci/perf.32bit-pop-114limb.sub-cmc.1G
-rwxr-xr-x 1 peter peter 8.4K May 19 04:29 a.out
-rw-r--r-- 1 peter peter 8.9K Jul 25  2017 fibonacci/perf.python-xnor-2n
-rw-r--r-- 1 peter peter 9.5K Jul 26  2017 fibonacci/fibonacci-1G-performance.asm
-rwxr-xr-x 1 peter peter 9.6K Apr 12 23:25 empty-args
-rw-r--r-- 1 peter peter 9.7K Dec 18 17:00 bubblesort.asm
-rwxr-xr-x 1 peter peter 9.9K Feb  6 23:34 parity-party/a.out
-rw-r--r-- 1 peter peter 9.9K Jul 25  2017 fibonacci/fibonacci-1G-performance.asm~
...

Vous pouvez filtrer les répertoires en passant par grep -v '^d'

Vous pouvez parfois utiliser un glob qui correspond uniquement aux fichiers et non aux répertoires, si vos noms de fichiers ont un modèle. par exemple ll -rSd **/*.jpg, ou même **/*.*fonctionne si aucun de vos noms de répertoire ne .s'y trouve, et tous les fichiers que vous voulez faire .

(Pour les personnes ayant un arrière-plan DOS: il n'y a rien de magique *.*sur Unix. Il correspond à n'importe quelle entrée de répertoire qui contient un point littéral. Mais à part les exécutables et parfois les fichiers texte, il est courant de donner des extensions aux noms de fichiers.)

@dessert souligne que vous en auriez besoin shopt -s dotglobpour correspondre à tous les fichiers.


Avec GNU find

S'il n'y a pas trop de fichiers pour tenir sur une seule lsligne de commande, find -exec ls {} +les mettre tous sur la ligne de commande où les lstrier.

find -not -type d -exec ls --color -lrSh {} +

Utiliser -not -type dau lieu d' -type féviter d'ignorer les liens symboliques, les canaux nommés, les sockets, les fichiers de périphérique et tout ce que vous avez dans vos répertoires.


Avec du:

du -ach | sort -h
....
4.0K    x86-modedetect-polyglot.o
8.0K    ascii-compress-base.asm
8.0K    dizzy-integer
8.0K    stopwatch-rdtsc.asm
8.0K    string-exponential.asm
8.0K    true-binary
12K     a.out
12K     bubblesort.asm
12K     casexchg
12K     empty-args
100K    parity-party
220K    fibonacci
628K    total

Désormais, les noms de répertoires sont triés dans la liste avec la somme totale de tout leur contenu, mais les fichiers individuels sont toujours inclus.

sort -h, aka --human-numeric-sort, trie les nombres avec des suffixes de taille comme les du -himpressions. Il est parfait pour une utilisation avec du.

J'utilise souvent du -sch * | sort -h, ou */pour obtenir uniquement des répertoires.

du -sch **/* | sort -hvous donnerait la sortie ci-dessus, si vous oubliez que cela dua une -aoption.

(J'ai seulement pris le temps de le chercher parce que je poste une réponse. Pour une utilisation interactive, je l'aurais probablement utilisé du -sch **/*.

Peter Cordes
la source