Taille de tous les fichiers d'une certaine extension dans une arborescence de répertoires

17

Je veux connaître la taille du fichier avec l'extension .o (fichier objet) dans mon dossier d'accueil.

Je peux trouver tous les fichiers objets en utilisant

find . -name '*.o'

Comment puis-je maintenant calculer la taille totale de ces fichiers?

alhelal
la source

Réponses:

24

Vous cherchez des tuyaux ( |). Ils sont un moyen de connecter plusieurs commandes et de passer la sortie d'une commande en entrée à une autre. Dans ce cas, vous souhaitez transmettre tous les noms de fichiers que vous trouvez en entrée du(qui calcule la taille). Cependant, étant donné duque les noms de fichiers attendus et les résultats de findsont juste une liste de texte (oui, le texte se compose de noms de fichiers, mais dune peut pas le savoir, tout ce qu'il voit est du texte), vous devez utiliser quelque chose comme xargsqui prendra chacun ligne de texte, traitez-le comme un nom de fichier et transmettez-le à du. En rassemblant tout cela, nous obtenons:

find . -name "*.o" | xargs du -sch
  • vous devez toujours citer les modèles auxquels vous donnez find(comme je l'ai fait ci-dessus:) "*.o". Si vous ne le faites pas, le shell étendra le *.oaux noms de tous les fichiers correspondants dans le répertoire courant. Cela n'a fonctionné dans ce cas que parce que vous n'aviez aucun fichier correspondant.

  • Les -schindicateurs pour dusont documentés dans man du:

    -c, --total
          produce a grand total
    -h, --human-readable
          print sizes in human readable format (e.g., 1K 234M 2G)
    -s, --summarize
          display only a total for each argument
    

Notez cependant que cela échouera pour les noms de fichiers contenant des espaces. Ce ne sera certainement pas un problème pour les fichiers objets, mais à l'avenir, si vous devez également gérer les espaces, utilisez:

find . -name "*.o" -print0 | xargs -0 du -sch

Les -print0marques findimpriment des lignes séparées par des valeurs NULL et les -0marques xargsprennent ces lignes en entrée.

Alternativement, vous pouvez faire findimprimer les tailles elles-mêmes, puis les additionner:

find . -name "*.o" -printf '%s\n' | awk '{c+=$1}END{print c}'

Cela contournera également le problème mentionné par @Serg dans les commentaires où il y a trop d'arguments et la commande est divisée en commandes distinctes.


Si vous utilisez bash(vous l' utilisez probablement), il existe un moyen plus simple:

shopt -s globstar 
du -sch **/*.o

La shopt globstarcommande fait **correspondre tous les fichiers et ou plusieurs sous-répertoires. Après l'avoir activé, **/*.ocorrespondra à tous les fichiers (et répertoires) dont le nom se termine .o, afin que nous puissions le transmettre directement à du.

Notez que, contrairement à l' findapproche, cela ne correspondra pas aux fichiers cachés (ceux dont le nom commence par un .). Pour les faire correspondre également, procédez comme suit:

shopt -s dotglob globstar
du -sch **/*.o
terdon
la source
Il y a un petit problème avec le premier. Il existe une chose telle que MAXARGS. Il y aura donc plusieurs itérations de du, et cela produira plusieurs totallignes. Voici un exemple: paste.ubuntu.com/23092752
Sergiy Kolodyazhnyy
@Serg true. J'ai ajouté une autre option qui évite cela.
terdon
Votre premier shopt globstarexemple laisse de côté le -s; J'ai dû utiliser shopt -s globstarsimilaire à votre deuxième exemple.
CrazyPyro
@CrazyPyro d'oh! Désolé, c'était une faute de frappe. Merci de l'avoir signalé. shopt OPTIONsans -sou ou -u(ou autre option, voir help shopt) imprime simplement la valeur actuelle de OPTION. Vous devez shopt -s OPTIONen activer un et shopt -u OPTIONle désactiver.
terdon
8

Utilisez -exec flag pour exécuter la ducommande avec ;(signification pour chaque fichier)

find . -name "*.o" -exec du -b {} \; | awk '{total+=$1}END{print total}' 

Exemple de sortie:

$ find . -name "*.txt"  -exec du -b {} \; | awk '{total+=$1}END{print total,"bytes" }'                                     
find: ‘./.cache/gvfs-burn’: Permission denied
find: ‘./.cache/unity’: Permission denied
852690242 bytes

findest récursif - ce qui signifie qu'il parcourt tous les sous-répertoires. Si vous voulez simplement obtenir le total de tous les *.ofichiers du répertoire actuel, faites simplement

du -b -c *.o
Sergiy Kolodyazhnyy
la source
0

avec perl:

perl -le 'map { $sum += -s } @ARGV; print $sum' -- *.pdf

Taille de tous les fichiers PDF non masqués dans le répertoire actuel.

fou
la source
1
D'accord, mais l'OP recherche des .ofichiers et ils pourraient se trouver dans des sous-répertoires. Vous pouvez également ajouter un }{avant print $sumpour éviter d'imprimer la somme pour chaque itération. Nous voulons seulement le dernier.
terdon