Réponses:
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
shopt globstarexemple laisse de côté le -s; J'ai dû utiliser shopt -s globstarsimilaire à votre deuxième exemple.
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.
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
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.
.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.
du, et cela produira plusieurstotallignes. Voici un exemple: paste.ubuntu.com/23092752