2010-12-14 4 views
3

J'ai un script bash qui doit connaître le nombre d'octets pour tous les fichiers gzip d'un répertoire. Pour l'instant, je suppose que c'est juste un seul répertoire sans sous-répertoires. Il est très tentant de faire quelque chose comme ceci:Nombre d'octets de tous les fichiers gzip dans un répertoire

du -scb /my/dir/*.gz|tail -n 1

Cependant, j'ai une tonne de fichiers. Le *.gz ne s'étendra-t-il pas à une sorte de condition de débordement? Existe-t-il un moyen plus rapide et plus sûr de vérifier ce numéro?

+0

Ce que vous avez semble bien. Toute implémentation décente prendrait en charge les fichiers 64 bits (plus grand que 2 Go, je veux dire), et donc les totaux 64 bits aussi. –

+1

@Chris Je pense qu'il s'inquiète de dépasser la limite de longueur de la ligne de commande. Sur la plupart des systèmes Linux, c'est assez énorme (128 Ko, si je me souviens bien) mais sur certains nix, c'est plutôt petit (je pense que sur Solaris, c'est quelque chose comme 255 octets). –

+0

La limite de longueur de ligne de commande est ma préoccupation. Y at-il un moyen de définir et d'obtenir cette valeur de bash? – User1

Répondre

4

Cela fonctionne et est "sûr":

(find . -type f -print0 | 
    xargs -0 stat -c '%s' | 
    tr '\n' '+'; echo 0) | 
    bc 

Comment ça marche:

  • Tout d'abord, utilisez find pour trouver des fichiers les '.gz'. Imprimez-les avec des séparateurs nuls, donc nous pouvons traiter des noms de fichiers bizarres.
  • xargs va décomposer les groupes de noms de fichiers en morceaux gérables. Donnez ces noms de fichiers à stat -c '%s' pour obtenir les tailles en octets (merci @Fritschy). Convertit les nouvelles lignes en +. L'écho ajoute un 0 supplémentaire à la fin plus un retour à la ligne. C'est ainsi que nous ne finissons pas avec un signe plus qui pend, et bc a besoin d'un retour à la ligne à la fin de son entrée.
  • Nourrir la somme énorme en bc.
+0

Nice, vérifiez 'stat (1)', qui peut stat un fichier et imprimer des informations selon un format donné. –

+0

@Fritschy: merci, je ne connaissais pas 'stat (1)'. Incorporé dans la réponse. –

1
echo $(($(find . -type f -name '*.gz' -printf '%s+') 0)) 

Si vous avez besoin énormes valeurs, changer '%s+'-'%s+0' et changer le $((... 0)) à ... | bc

Modifier: Pour les valeurs encore plus, vous pouvez utiliser %k au lieu de %s, vous donner des kilo-octets. Puisque l'entier peut déborder.

Je ne sais pas si la longueur des arguments de executables sont Puisque nous n'utilisons Encastrements bash, problème.

Questions connexes