web-dev-qa-db-fra.com

Afficher la somme des tailles de fichier dans la liste des répertoires

La commande de liste de répertoires Windows dir comporte à la fin une ligne indiquant la quantité totale d'espace occupé par les fichiers répertoriés. Par exemple, dir *.exe affiche tous les .exe fichiers dans le répertoire courant, leurs tailles et la somme totale de leurs tailles. J'aimerais avoir des fonctionnalités similaires avec mon alias dir dans bash, mais je ne sais pas exactement comment procéder.

Actuellement, j'ai alias dir='ls -FaGl' dans mon .bash_profile, montrant

drwxr-x---+  24 mattdmo  4096 Mar 14 16:35 ./
drwxr-x--x. 256 root    12288 Apr  8 21:29 ../
-rw-------    1 mattdmo 13795 Apr  4 17:52 .bash_history
-rw-r--r--    1 mattdmo    18 May 10  2012 .bash_logout
-rw-r--r--    1 mattdmo   395 Dec  9 17:33 .bash_profile
-rw-r--r--    1 mattdmo   176 May 10  2012 .bash_profile~
-rw-r--r--    1 mattdmo   411 Dec  9 17:33 .bashrc
-rw-r--r--    1 mattdmo   124 May 10  2012 .bashrc~
drwx------    2 mattdmo  4096 Mar 24 20:03 bin/
drwxrwxr-x    2 mattdmo  4096 Mar 11 16:29 download/

par exemple. Prendre les réponses de cette question :

dir | awk '{ total += $4 }; END { print total }'

ce qui me donne le total, mais n'imprime pas le répertoire lui-même. Existe-t-il un moyen de modifier cela en un script à une ligne ou Shell pour que je puisse passer les arguments ls que je veux dir et obtenir une liste complète plus la somme totale? Par exemple, je voudrais exécuter dir -R *.jpg *.tif pour obtenir la liste et la taille totale de ces types de fichiers dans tous les sous-répertoires. Idéalement, ce serait bien si je pouvais obtenir la taille de chaque sous-répertoire, mais ce n'est pas essentiel.

82
MattDMo

La fonction suivante fait la plupart de ce que vous demandez:

dir () { ls -FaGl "${@}" | awk '{ total += $4; print }; END { print total }'; }

... mais cela ne vous donnera pas ce que vous demandez de dir -R *.jpg *.tif, car ce n'est pas ainsi ls -R travaux. Vous voudrez peut-être jouer avec l'utilitaire find pour cela.

26
user27282

Il existe déjà une commande UNIX pour cela: du

Faites juste:

du -ach 

Selon la convention, vous pouvez ajouter un ou plusieurs chemins de fichiers ou de répertoires à la fin de la commande. -h est une extension pour convertir la taille dans un format convivial, -a vous donne la taille "apparente" (taille du fichier au lieu de l'utilisation du disque) et -c donne un total à la fin.

168
Pete Cornell

Vous pouvez utiliser du -h -c directory|tail -1

Cela générera une seule ligne avec l'utilisation de la mémoire.

23
mani deepak

Imprimez simplement la ligne actuelle dont vous additionnez le total:

dir | awk '{ print; total += $4 }; END { print "total size: ",total }'
8
Mauritz Hansen

avec Perl:

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

Taille de tous les fichiers non cachés PDF dans le répertoire courant.

6
ingopingo

L'ajout de ce qui suit à .bash_profile ou .bashrc fonctionne pour moi.

dir ()
{
find . -iname "$@" -exec ls -lh {} \;
find . -iname "$@" -print0|xargs -r0 du -csh|tail -n 1;
}

Maintenant, quand je fais un dir * .mp3, il le fait récursivement et affiche le total à la fin. Vous pouvez contrôler la profondeur souhaitée en ajoutant un paramètre maxdepth à la recherche. Je sais que courir deux fois n'est pas une idée très efficace. Mais je ne pouvais pas penser à une meilleure façon. Au moins, il fait le travail.

1
bagavadhar

Utiliser d et une instruction awk comme celle mentionnée ci-dessus vous fournira ce que vous recherchez.

Exemple: du /home/abc/Downloads/*.jpg | awk '{ print; total += $1 }; END { print "total size: ",total }'

Cela répertoriera tous les fichiers du dossier Téléchargements de l'utilisateur abc se terminant par .jpg et imprime la somme de tous ces fichiers à la fin de la liste.

1
user3085123
du path_to_your_files/*.jpg | awk '{ total += $1 }; END { print total }'
0
Tamer Mansour

Pour compter les fichiers dans un répertoire à l'aide d'un masque, j'ai tendance à suivre cette approche:

Pour les octets

du -ac --bytes  | grep "Zip$" | awk '{ print; total += $1 }; END { print "total lobsters: ", total, " Bytes" }'

Pour les kilo-octets

du -ac --bytes  | grep "Zip$" | awk '{ print; total += $1 }; END { print "total lobsters: ", total/1024, " KB" }'

Pour les mégaoctets

du -ac --bytes  | grep "Zip$" | awk '{ print; total += $1 }; END { print "total lobsters: " total/1024/1024 " MB" }'

Vous avez eu l'idée.

La répartition est simple:

  • d - utilisation du disque
    • -a - tous les fichiers
    • -c - total d'octets
    • --bytes - affiche la sortie en octets [dans les versions plus récentes de bash, je ne sais plus si cela s'applique plus]
  • grep - g lobal r egular e xpression p rint [imprime les modèles de correspondance de sortie]
    • "Zip $" - motif correspondant. 'Zip' est la chaîne, et le '$' indique la fin de la chaîne/ligne/etc - dans ce cas, faites correspondre les lignes qui [~ # ~] fin [~ # ~] avec ' Zip *: français'. Inversement, placer '^' au début de la chaîne indique que le motif sera au début de la chaîne [c'est-à-dire: "^ start" correspondra aux lignes au début avec le mot 'start' ] - Avec cette connaissance, encapsuler une chaîne dans ^ et $ respectivement, fera correspondre les lignes qui commencent/finissent avec le modèle utilisé. "^ hello people $" fera correspondre les chaînes disant 'hello people'. "^ hello (. *) people $" fera correspondre les chaînes disant 'hello french people' et 'hello coding people', mais pas 'hello coding people with no lives'
  • awk - un langage de script programmé par [~ # ~] a [~ # ~] ho =, [~ # ~] w [~ # ~] einberger , et [~ # ~] k [~ # ~] ernighan . Pas un nom très original, mais une langue très puissante qui est excellente pour le traitement de texte et l'extraction de données.
    • { impression; total + = 1 $}
      • print - imprime la ligne en cours d'itération
      • total + = $ 1 - initialiser la variable total si ce n'est pas déjà fait, et ajouter le premier bloc séparé par le field separator, dans ce cas un space character. Cela peut être modifié par le -F drapeau.
      • ; - terminateur de ligne/instruction. vous pouvez mettre plusieurs instructions awk sur une seule ligne en utilisant ceci, comme pour terminer les instructions de ligne de commande linux. Sinon, vous pourriez les avoir dans un objet multi-lignes encore entouré de {...}
      • END - cela signifie effectivement que awk exécutera les actions spécifiées avant de se terminer.
    • {print "total lobsters:" total "Bytes"}
      • print "total lobsters:" - la première partie de la chaîne est sortie
      • total - la variable contenant la somme totale des lignes itérées sur
      • "Octets" - dernière partie de la chaîne imprimée, collée à la fin des deux déclarations précédentes
      • évidemment, ces trois déclarations sont encapsulées dans {} comme la première partie.

Donc, en passant par un exemple dans un cas où nous voulons compter le nombre total de fichiers Zip dans un répertoire:

du -ac --bytes

836544  ./wp-content/themes/astra.1.8.1.Zip
934364  ./wp-content/themes/astra.2.0.1.Zip
400033  ./wp-content/uploads/2019/09/premium-addons-for-elementor-3.2.9-WJdFQT1mLd3GA81lQEAo.Zip
117351218       ./wp-content/uploads/backwpup-fc5928-temp/2019-05-30_00-47-01_TX6FSKC601.Zip
1192275 ./wp-content/plugins/essential-addons-elementor-master.Zip
170     ./wp-content/plugins/gravityforms/images/doctypes/icon_Zip.gif
1969651 ./wp-content/plugins/acf.Zip
4284    ./wp-content/plugins/types/application/controllers/api/handler/import_from_Zip_file.php

Deux composants de sortie, col 1 représenté par les valeurs numériques: 836544, 934364 ... etc, et col 2 étant le chemin du fichier.

Cependant, comme il y a deux lignes qui ne correspondent pas à ce que nous voulons - icon_Zip.gif et import_from_Zip_file.php - nous voulons les exclure. Puisque du ne fournit pas un moyen de filtrer récursivement par extension (à ma connaissance), nous filtrons en utilisant grep

grep "Zip$"

Cela a effectivement la sortie de du canalisée et filtre les lignes qui se terminent par Zip =, éliminant les deux enregistrements dont nous ne voulons pas:

836544  ./wp-content/themes/astra.1.8.1.Zip
934364  ./wp-content/themes/astra.2.0.1.Zip
400033  ./wp-content/uploads/2019/09/premium-addons-for-elementor-3.2.9-WJdFQT1mLd3GA81lQEAo.Zip
117351218       ./wp-content/uploads/backwpup-fc5928-temp/2019-05-30_00-47-01_TX6FSKC601.Zip
1192275 ./wp-content/plugins/essential-addons-elementor-master.Zip
1969651 ./wp-content/plugins/acf.Zip

Ensuite, awk analyse chaque ligne, avec les chiffres dans col 1 étant stocké dans $1

Nous obtenons ceci:

836544  ./wp-content/themes/astra.1.8.1.Zip
934364  ./wp-content/themes/astra.2.0.1.Zip
400033  ./wp-content/uploads/2019/09/premium-addons-for-elementor-3.2.9-WJdFQT1mLd3GA81lQEAo.Zip
117351218       ./wp-content/uploads/backwpup-fc5928-temp/2019-05-30_00-47-01_TX6FSKC601.Zip
1192275 ./wp-content/plugins/essential-addons-elementor-master.Zip
1969651 ./wp-content/plugins/acf.Zip
total lobsters:  128.339  MB
0
Barry Chapman

Pour obtenir les deux, la sortie dir et le calcul de la taille, sans utiliser aucune des autres options proposées, vous pouvez utiliser tee (1) et la substitution de processus ...

dir | tee >( awk '{ total += $4 }; END { print total }' )
0
Janis