du qui compte le nombre de fichiers / répertoires plutôt que la taille

13

J'essaie de nettoyer un disque dur qui contient toutes sortes de conneries accumulées au fil des ans. dua aidé à réduire l'utilisation du disque, mais le tout n'est toujours pas difficile à cause de la taille totale, mais du nombre total de fichiers et de répertoires.

Existe-t-il un moyen de faire quelque chose comme, dumais sans compter la taille des fichiers, mais plutôt le nombre de fichiers et de répertoires? Par exemple: un fichier est 1 et un répertoire est le nombre récursif de fichiers / répertoires qu'il contient + 1.

Edit: j'aurais dû être plus clair. Je voudrais non seulement connaître le nombre total de fichiers / répertoires dans /, mais aussi dans /home, /usretc., et dans leurs sous-répertoires, de manière récursive, comme dupour la taille.

Jesse
la source
2
Pensez que vous cherchez peut-être quelque chose comme une version légèrement modifiée des réponses ici superuser.com/questions/198817/…
James

Réponses:

11

J'ai trouvé du --inodesutile, mais je ne sais pas quelle version de ducelui - ci nécessite. Sur Ubuntu 17.10, les travaux suivants:

du --inodes      # all files and subdirectories
du --inodes -s   # summary
du --inodes -d 2 # depth 2 at most

Combinez avec | sort -nrpour trier par ordre décroissant du nombre d'inodes contenus.

krlmlr
la source
1
Cela ressemble beaucoup plus à ce que je veux qu'à la réponse acceptée.
Sridhar Sarnobat
8

La façon la plus simple semble être find /path/to/search -ls | wc -l

La recherche est utilisée pour parcourir tous les fichiers et dossiers.
-lspour lister (imprimer) tous les noms. Il s'agit d'une valeur par défaut et si vous la laissez de côté, elle fonctionnera toujours de la même manière sur presque tous les systèmes. (Presque, car certains peuvent avoir des valeurs par défaut différentes). C'est une bonne habitude de l'utiliser explicitement cependant.

Si vous utilisez simplement la find /path/to/search -lspartie, tous les fichiers et répertoires seront imprimés sur votre écran.


wcest le nombre de mots. l' -loption lui dit de compter le nombre de lignes.

Vous pouvez l'utiliser de plusieurs manières, par exemple

  • wc testfile
  • fichier de test de chat | toilettes

La première option permet à wc d'ouvrir un fichier et de compter le nombre de lignes, de mots et de caractères dans ce fichier. La deuxième option fait de même mais sans nom de fichier, elle lit depuis stdin.


Vous pouvez combiner des commandes avec un tuyau |. La sortie de la première commande sera dirigée vers l'entrée de la deuxième commande. Ainsi find /path/to/search -ls | wc -lutilise find pour lister tous les fichiers et répertoires et alimente la sortie vers wc. Wc compte alors le nombre de lignes.

(Une autre alternative aurait été «ls | wc», mais find est beaucoup plus flexible et un bon outil pour apprendre.)


[Modifier après commentaire]

Il pourrait être utile de combiner la recherche et l'exec.

Par exemple find / -type d ! \( -path proc -o -path dev -o -path .snap \) -maxdepth 1 -exec echo starting a find to count to files in in {} \;, listera tous les répertoires dans /, sauf certains que vous ne souhaitez pas rechercher. Nous pouvons déclencher la commande précédente sur chacun d'eux, produisant une somme de fichiers par dossier dans /.

Toutefois:

  1. Cela utilise l'extension spécifique GNU -maxdepth.
    Cela fonctionnera sur Linux, mais pas sur n'importe quel Unix-a-alike.
  2. Je soupçonne que vous pourriez réellement vouloir un certain nombre de fichiers fo pour chaque sous-répertoire.
Hennes
la source
Désolé, pas seulement un niveau de profondeur, mais pour tous les niveaux (c'est ce que je voulais dire par "récursivement" dans mon montage).
Jesse
Au lieu de l'écho d'exécution, vous déclenchez une recherche | wc pour chaque dir. Je sais que c'est possible, mais je n'arrive pas à découvrir comment aujourd'hui. Je suppose que je continue de faire la même erreur d'une manière ou d'une autre. * Va préparer du café *.
Hennes
4

Le script PHP suivant fait l'affaire.

#!/usr/bin/php
<?php 

function do_scan($dir, $dev) {
  $total = 1;

  if (\filetype($dir) === 'dir' && \lstat($dir)['dev'] == $dev) {
    foreach (\scandir($dir) as $file) {
      if ($file !== '.' && $file !== '..') {
        $total += do_scan($dir . \DIRECTORY_SEPARATOR . $file, $dev);
      }
    }

    print "$total\t$dir\n";
  }

  return $total;
};

foreach (\array_slice($argv, 1) as $arg) {
  do_scan($arg, \lstat($arg)['dev']);
}

Mettez-le dans un fichier (par exemple, " treesize"), chmod +xet exécutez-le avec ./treesize . | sort -rn | less.

Jesse
la source
Pourquoi est-ce la réponse acceptée?! Vous supposez que php est sur la machine, ce qui n'est pas toujours le cas. Le script n'est pas documenté et spécifique. Bien qu'il soit correct de répondre à votre propre question sur SE, cette réponse ne fournit même pas de réponse à votre propre question ; ou vous n'avez pas posé la question que vous aviez en tête lorsque le problème est survenu ... Malheureusement je ne peux pas le dévaloriser, je dois faire peu de point ... quand même, mauvaise réponse!
user1810087
Je ne peux pas écrire le script dans n'importe quelle langue sans supposer qu'un interprète pour cette langue est installé. Le script imprime le nombre total de fichiers et de répertoires sous chaque répertoire de manière récursive. Donc, ducela compte simplement au lieu de sommer la taille, ce qui est exactement ce que la question d'origine a demandé.
Jesse
2

ncdu est idéal pour cela!

À partir de la page de manuel, vous pouvez également afficher les nombres par répertoire et les classer par nombre:

[...]
KEYS
       C   Order by number of items (press again for descending order)
[...]
       c   Toggle display of child item counts.

Par exemple:

sortie ncdu

jobevers
la source
1

Exploitez le fait que les répertoires et les fichiers sont séparés par /. Ce script répond à vos critères, mais sert à inspirer une solution complète. Vous devriez également envisager d'indexer vos fichiers avec Locate.

geee: /R/tb/tmp
$ find  2>/dev/null | awk -F/ -f filez  | sort -n
files:  57
3       imagemagick
7       portage
10      colemak-1.0
25      minpro.com
42      monolith
80      QuadTree
117     themh
139     skyrim.stings
185     security-howto
292     ~t
329     skyrim
545     HISTORY
705     minpro.com-original
1499    transmission-2.77
23539   ugent-settings

>

$ cat filez
{
a[$2]++;     # $1= folder,  $2 = everything inside folder.
}

END {
        for (i in a) {
                if (a[i]==1) {files++;}
                else { printf "%d\t%s\n", a[i], i; }
        }
        print "files:\t" files
}

>

 $ time locate /  | awk -F/ -f /R/tb/tmp/filez  | sort -n
 files:  13
 2
 2       .fluxbox
 10      M
 11      BIN
 120     bin
 216     sbin
 234     boot
 374     R
 854     dev
 1351    lib
 2018    etc
 9274    media
 30321   opt
 56516   home
 93625   var
 222821  usr
 351367  mnt
 time: Real 0m17.4s  User 0m4.1s  System 0m3.1s
Ярослав Рахматуллин
la source
2
Pourquoi ai-je .fluxbox dans /? : D
Ярослав Рахматуллин
1

Voici une solution qui utilise bash, inspirée d'un article d'Unix et Linux .

find . -type d | while read -r dir; do \
    printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done

S'il y a des dossiers dont vous ne voulez pas voir les détails, comme .git, vous pouvez les exclure de la liste avec grep.

find . -type d |grep -v "./.git/.*" | while read -r dir; do \
    printf "%s:\t" "$dir"; find "$dir" -type f | wc -l; done
Don Kirkby
la source