Comment puis-je obtenir la taille dun fichier dans un script bash?

Comment puis-je obtenir la taille dun fichier dans un script bash?

Comment attribuer ceci à une variable bash pour pouvoir lutiliser plus tard?

Commentaires

  • stackoverflow.com/questions/5920333/how-to-check-size-of-a-file LOL pour la migration 🙂
  • Associez-le avec pv et cat pour une commande de copie indiquant la progression et lETA 🙂
  • stat -c% s fichier. name
  • En cas de problème XY (très étroit), cest bien: si tout ce dont vous avez besoin est de tester le fichier a une taille différente de zéro, bash a une expression conditionnelle -s, vous pouvez donc simplement tester si un fichier a une longueur différente de zéro avec if [ -s file ]; then echo "file has nonzero size" ; fi

Réponse

Votre meilleur pari si vous utilisez un système GNU:

stat --printf="%s" file.any 

De man stat :

Taille totale de% s, en octets

Dans un script bash:

#!/bin/bash FILENAME=/home/heiko/dummy/packages.txt FILESIZE=$(stat -c%s "$FILENAME") echo "Size of $FILENAME = $FILESIZE bytes." 

REMARQUE: voir

Réponse de @chbrown pour savoir comment utiliser stat dans le terminal sous Mac OS X.

Commentaires

  • @ haunted85 stat est le moyen le plus simple, en supposant que vous ‘ utilisez Linux ou Cygwin (stat nest pas ‘ t standard). wc -c as suggéré par Eug é ne est portable.
  • stat: illegal option -- c
  • stat --printf="%s" file.txt ne ‘ t afficher nimporte quoi sur Debian Jessie …
  • Sur MacOS, cela fonctionne: stat -f%z myfile.tar
  • @woohoo Votre invite écrase la sortie. man stat dit que –printf omet la nouvelle ligne de fin. Utilisez --format ou -c pour voir la sortie. Obtenez plus dinformations en comparant stat --printf="%s" file.any | xxd - à stat -c "%s" file.any | xxd -

Réponse

file_size_kb=`du -k "$filename" | cut -f1` 

Le problème avec lutilisation de stat est quil sagit dune extension GNU (Linux). du -k et cut -f1 sont spécifiés par POSIX et sont donc portables sur nimporte quel système Unix.

Solaris, par exemple, est livré avec bash mais pas avec stat . Donc, ce nest pas entièrement hypothétique.

ls a un problème similaire en ce que le format exact de la sortie nest pas spécifié, donc lanalyse de sa sortie ne peut pas être effectuée de manière portative . du -h est aussi une extension GNU.

Tenez-vous en aux constructions portables lorsque cela est possible, et vous faciliterez la vie de quelquun à lavenir. Peut-être la vôtre.

Commentaires

  • du ne ‘ taille du fichier, cela donne une indication de lespace utilisé par le fichier, qui est légèrement différent (généralement la taille indiquée par du est la taille du fichier arrondie au plus proche nombre de blocs, où un bloc fait généralement 512 ou 1 Ko ou 4 Ko).
  • @Gilles, les fichiers épars (cest-à-dire ceux avec des trous) indiquent moins que la longueur.
  • Ceci, avec --bytes ou -b au lieu de -k, devrait être la réponse acceptée.
  • @fralau: LOP souhaite  » attribuer ceci à une variable bash afin de pouvoir lutiliser plus tard « , il est donc beaucoup plus probable quils veuillent un actu une valeur numérique, pas une approximation lisible par lhomme. De plus, -h est une extension GNU; ce nest pas standard
  • Lutilisation de du avec --apparent-size lindicateur renverra un autre taille précise (comme indiqué sur lhomme: print apparent sizes, rather than disk usage; although the apparent size is usually smaller, it may be larger due to holes in ('sparse') files, internal fragmentation, indirect blocks, and the like)

Réponse

Vous pouvez également utiliser la commande » word count « (wc):

wc -c "$filename" | awk "{print $1}" 

Le problème avec wc est quil « ajoutera le nom du fichier et indentera la sortie. Par exemple:

$ wc -c somefile.txt 1160 somefile.txt 

Si vous souhaitez éviter de chaîner un langage interprété complet ou un éditeur de flux juste pour obtenir un compte de taille de fichier, redirigez simplement lentrée du fichier afin que wc ne voit jamais le nom du fichier:

wc -c < "$filename" 

Ce dernier formulaire peut être utilisé avec la substitution de commande pour saisir facilement la valeur que vous cherchiez en tant que variable shell, comme mentionné par Gilles ci-dessous.

size="$(wc -c <"$filename")" 

Commentaires

  • wc -c <"$FILENAME" donne la taille sans autre cruft, donc size=$(wc -c <"$FILENAME").
  • Encore un point: je viens de le tester et wc -c < file semble être très rapide, du moins sous OS X. Je ‘ m deviner que wc a le cerveau pour essayer de statuer le fichier si seulement -c est spécifié.
  • @EdwardFalk: GNU wc -c utilise fstat, mais recherche ensuite lavant-dernier bloc du fichier et lit le dernier jusquà st_blksize octets. Apparemment cest parce que les fichiers sous Linux ‘ s /proc et /sys, par exemple, ont des tailles de statistiques qui ne sont quapproximatives , et wc souhaite indiquer la taille réelle, pas la taille indiquée par les statistiques. Je suppose que ce serait bizarre pour wc -c de signaler une taille différente de wc, mais cela ‘ na pas lidée de lire les données du fichier sil ‘ est un fichier disque normal, et quil ‘ nest pas en mémoire. Ou pire, un stockage sur bande proche de la ligne …
  • Il semble que printf voit toujours lindentation, par exemple printf "Size: $size" – > size: <4 spaces> 54339. En revanche, echo ignore les espaces. Un moyen de le rendre cohérent?
  • @keithpjolley: en appelant fstat. Essayez dexécuter strace wc -c </etc/passwd et vous verrez ce quil fait.

Answer

BSD « s (macOS » s) stat a un indicateur dargument de format différent et des spécificateurs de champ différents. Depuis man stat(1):

  • -f format: affichez les informations au format spécifié. Voir la section FORMATS pour une description des formats valides.
  • … la section FORMATS …
  • z: La taille de fichier en octets.

Donc tous ensemble maintenant:

stat -f%z myfile1.txt 

REMARQUE: voir @ b01 « s answer pour savoir comment utiliser la commande stat sur les systèmes GNU / Linux. 🙂

Commentaires

  • Notez quil sagit dune solution uniquement BSD. Elle ne ‘ t fonctionne avec GNU stat, malheureusement.

Réponse

Cela dépend de ce que vous entendez par taille .

size=$(wc -c < "$file") 

vous donnera le nombre doctets qui peuvent être lus à partir du fichier. IOW, cest la taille du contenu du fichier. Il lira cependant le contenu du fichier (sauf si le fichier est un fichier normal ou un lien symbolique vers un fichier normal dans la plupart des implémentations de wc comme optimisation). Cela peut avoir des effets secondaires. Par exemple, pour un tube nommé, ce qui a été lu ne peut plus être lu à nouveau et pour des choses comme /dev/zero ou /dev/random qui sont de taille infinie, cela va prendre un certain temps. Cela signifie également que vous avez besoin de l’autorisation read sur le fichier, et le horodatage du dernier accès du fichier peut être mis à jour.

Cest standard et portable, mais notez que certaines implémentations de wc peuvent inclure des blancs de début dans cette sortie. Une façon de sen débarrasser est dutiliser:

size=$(($(wc -c < "$file"))) 

ou déviter une erreur concernant une expression arithmétique vide dans dash ou yash lorsque wc ne produit aucune sortie (comme lorsque le fichier ne peut « pas être ouvert):

size=$(($(wc -c < "$file") +0)) 

ksh93 a wc intégré (à condition que vous lactiviez, vous pouvez également linvoquer comme command /opt/ast/bin/wc) ce qui en fait le plus efficace pour les fichiers normaux de ce shell.

Différents systèmes ont une commande appelée stat qui « est une interface avec les appels système stat() ou lstat().

Ces informations de rapport se trouvent dans le inode. Lune de ces informations est lattribut st_size. Pour les fichiers normaux, cest la taille du contenu (combien de données peuvent être lues à partir de celui-ci en labsence derreur (cest ce que la plupart des implémentations de wc -c utilisent dans leur optimisation) ). Pour les liens symboliques, cest la taille en octets du chemin cible. Pour les canaux nommés, selon le système, il sagit de 0 ou du nombre doctets actuellement dans le tampon de canal. Idem pour les périphériques bloqués où, selon le système, vous obtenez 0 ou la taille en octets du stockage sous-jacent.

Vous navez pas besoin dune autorisation de lecture sur le fichier pour obtenir ces informations, uniquement lautorisation de recherche sur le répertoire auquel il est lié.

Par ordre chronologique, il y a:

  • IRIX stat (90 « s):

    stat -qLs -- "$file" 

    renvoie lattribut st_size de $file (lstat()) ou:

    stat -s -- "$file" 

    même sauf lorsque $file est un lien symbolique auquel cas il « est le st_size du fichier après la résolution du lien symbolique.

  • zsh stat builtin (désormais également appelé zstat) dans le module zsh/stat (chargé avec zmodload zsh/stat) (1997):

    stat -L +size -- $file # st_size of file stat +size -- $file # after symlink resolution 

    ou pour stocker dans une variable:

    stat -L -A size +size -- $file 

    évidemment, cest le plus efficace en ce shell.

  • GNU stat (2001); également dans BusyBox stat depuis 2 005 (copié depuis GNU stat):

    stat -c %s -- "$file" # st_size of file stat -Lc %s -- "$file" # after symlink resolution 

    (notez la signification de -L est inversé par rapport à IRIX ou zsh stat.

  • BSD stat (2002):

    stat -f %z -- "$file" # st_size of file stat -Lf %z -- "$file" # after symlink resolution 

Ou vous pouvez utiliser la fonction stat() / lstat() dun langage de script comme perl:

perl -le "print((lstat shift)[7])" -- "$file" 

AIX a également un istat commande qui videra tous les stat() (et non lstat(), donc ne fonctionnera pas sur les liens symboliques ) et que vous pourriez post-traiter avec, par exemple:

LC_ALL=C istat "$file" | awk "NR == 4 {print $5}" 

(merci @JeffSchaller pour le aide à trouver les détails ).

Dans tcsh:

@ size = -Z $file:q 

(taille après la résolution du lien symbolique)

Bien avant que GNU nintroduise sa commande stat, la même chose pouvait être obtenue avec GNU find commande avec son prédicat -printf (déjà en 1991):

find -- "$file" -prune -printf "%s\n" # st_size of file find -L -- "$file" -prune -printf "%s\n" # after symlink resolution 

Un problème est cependant que ne « t fonctionne si $file commence par - ou est un prédicat find (comme !, ( …).

La commande standard pour obtenir le stat() / lstat() les informations sont ls.

POSIXly, vous pouvez faire:

LC_ALL=C ls -dn -- "$file" | awk "{print $5; exit}" 

et ajoutez -L pour le même après la résolution du lien symbolique. Cela ne fonctionne pas pour les fichiers de périphérique, mais où le champ 5 ème est le numéro principal de l’appareil au lieu de la taille.

Pour les périphériques en mode bloc, les systèmes où stat() renvoie 0 pour st_size, ont généralement dautres API pour signaler la taille du périphérique bloc. Par exemple, Linux a le BLKGETSIZE64 ioctl(), et la plupart des distributions Linux sont désormais livrées avec une commande blockdev qui peut en faire usage:

blockdev --getsize64 -- "$device_file" 

Cependant, vous avez besoin dune autorisation de lecture sur le fichier de périphérique pour cela. Il est généralement possible de calculer la taille par dautres moyens. Par exemple (toujours sous Linux):

lsblk -bdno size -- "$device_file" 

Devrait fonctionner sauf pour les appareils vides.

Une approche qui fonctionne pour tous les fichiers recherchés (ainsi que les fichiers normaux, la plupart des périphériques de bloc et certains périphériques de caractères) consiste à ouvrir le fichier et à chercher jusquà la fin:

  • Avec zsh (après chargement du module zsh/system):

    {sysseek -w end 0 && size=$((systell(0)))} < $file 
  • Avec ksh93:

    < "$file" <#((size=EOF)) 

    ou

    { size=$(<#((EOF))); } < "$file" 
  • avec perl:

    perl -le "seek STDIN, 0, 2 or die "seek: $!"; print tell STDIN" < "$file" 

Pour les canaux nommés, nous « avons vu que certains systèmes (AIX, Solaris, HP / UX au moins) rendent la quantité de données dans le tampon de canal disponible dans stat() » s st_size. Certains (comme Linux ou FreeBSD) ne le font pas.

Sous Linux au moins, vous pouvez utiliser FIONREAD ioctl() après avoir ouvert le tube (en mode lecture + écriture pour éviter quil ne se bloque):

fuser -s -- "$fifo_file" && perl -le "require "sys/ioctl.ph"; ioctl(STDIN, &FIONREAD, $n) or die$!; print unpack "L", $n" <> "$fifo_file" 

Cependant notez que tant quil ne « t lit pas le contenu du tube, la simple ouverture du tube nommé ici peut encore avoir des effets secondaires. Nous « utilisons fuser pour vérifier dabord que certains processus ont déjà le tuyau ouvert pour remédier à cela, mais ce » nest pas infaillible comme fuser peut ne pas pouvoir vérifier tous les processus.

Pour linstant, nous navons considéré que la taille des données primaires associées aux fichiers.Cela ne prend pas en compte la taille des métadonnées et toute linfrastructure de support nécessaire pour stocker ce fichier.

Un autre attribut dinode renvoyé par stat() est st_blocks. Cest le nombre de blocs de 512 octets utilisé pour stocker les données du fichier (et parfois certaines de ses métadonnées comme les attributs étendus sur les systèmes de fichiers ext4 sous Linux). « t inclure linode lui-même ou les entrées dans les répertoires auxquels le fichier est lié.

La taille et lutilisation du disque ne sont pas nécessairement étroitement liées à la compression, à la rareté (parfois certaines métadonnées), à linfrastructure supplémentaire comme les blocs indirects dans certains systèmes de fichiers ont une influence sur ces derniers.

Cest typiquement ce que du utilise pour signaler lutilisation du disque. La plupart des commandes listées ci-dessus pourront obtenir ces informations.

  • POSIXLY_CORRECT=1 ls -sd -- "$file" | awk "{print $1; exit}"
  • POSIXLY_CORRECT=1 du -s -- "$file" (pas pour les répertoires où cela inclurait le disque usag e des fichiers quil contient).
  • GNU find -- "$file" -printf "%b\n"
  • zstat -L +block -- $file
  • GNU stat -c %b -- "$file"
  • BSD stat -f %b -- "$file"
  • perl -le "print((lstat shift)[12])" -- "$file"

Commentaires

  • clairement la réponse la plus complète et la plus informative. Merci. Je peux lutiliser pour créer des scripts bash multiplateformes en utilisant les informations de statistiques BSD et GNU
  • Fait amusant: GNU coreutils wc -c utilise fstat, mais lit ensuite le dernier jusquà st_blksize octets. Apparemment cest parce que les fichiers sous Linux ‘ s /proc et /sys, par exemple, ont des tailles de statistiques qui ne sont quapproximatives . Cest bon pour lexactitude, mais mauvais si la fin du fichier est sur le disque et non en mémoire (surtout sil est utilisé sur de nombreux fichiers dans une boucle). Et très mauvais si le fichier est migré vers stockage sur bande de proximité , ou par exemple un système de fichiers FUSE à décompression transparente.
  • cela ne fonctionnerait pas aussi ls -go file | awk '{print $3}'
  • @StevenPenny ces -go seraient ceux de SysV, ils ne fonctionneraient ‘ sur les BSD (optionnel (XSI) dans POSIX). Vous ‘ avez également besoin de ls -god file | awk '{print $3; exit}' (-d pour quil fonctionne sur les répertoires, exit pour les liens symboliques avec des retours à la ligne dans la cible). Les problèmes avec les fichiers de périphériques persistent également.
  • @ αғsнιη lAPI Unix ne fait aucune distinction entre les fichiers texte et binaires. Il ‘ est toutes les séquences doctets. Certaines applications peuvent vouloir interpréter ces octets comme du texte mais évidemment pas wc -c qui indique le nombre doctets.

Réponse

Ce script combine de nombreuses façons de calculer la taille du fichier:

( du --apparent-size --block-size=1 "$file" 2>/dev/null || gdu --apparent-size --block-size=1 "$file" 2>/dev/null || find "$file" -printf "%s" 2>/dev/null || gfind "$file" -printf "%s" 2>/dev/null || stat --printf="%s" "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null || wc -c <"$file" 2>/dev/null ) | awk "{print $1}" 

Le script fonctionne sur de nombreux systèmes Unix y compris Linux, BSD, OSX, Solaris, SunOS, etc.

La taille du fichier indique le nombre doctets. Il sagit de la taille apparente, qui correspond aux octets que le fichier utilise sur un disque typique, sans compression spéciale, ni zones creuses spéciales, ni blocs non alloués, etc.

Ce script a une version de production avec plus daide et plus doptions ici: https://github.com/SixArm/file-size

Réponse

stat semble faire cela avec le moins dappels système:

$ set debian-live-8.2.0-amd64-xfce-desktop.iso $ strace stat --format %s $1 | wc 282 2795 27364 $ strace wc --bytes $1 | wc 307 3063 29091 $ strace du --bytes $1 | wc 437 4376 41955 $ strace find $1 -printf %s | wc 604 6061 64793 

La réponse

ls -l filename vous donnera de nombreuses informations sur un fichier, y compris sa taille, ses autorisations et son propriétaire.

La taille du fichier dans la cinquième colonne, et est affichée en octets. Dans lexemple ci-dessous, la taille du fichier est légèrement inférieure à 2 Ko:

-rw-r--r-- 1 user owner 1985 2011-07-12 16:48 index.php 

Modifier: Ce nest apparemment pas aussi fiable que la commande stat.

Commentaires

  • Je pense que les commandes ls -l et stat donnent des informations de taille fiables. Je nai trouvé aucune référence au contraire. ls -s donnera la taille en nombre de blocs.
  • @ dabest1 il ‘ nest pas fiable dans un sens que dans un autre unix, leur sortie peut être différente (et dans certains unix cest le cas).
  • Oui, IIRC, Solaris na ‘ t afficher le nom du groupe par défaut, conduisant à moins de colonnes dans la sortie.
  • Comme la taille est purement numérique, entourée despaces blancs, et que lannée de date est purement numérique, dans un format défini, il serait possible dutiliser une expression régulière pour traiter lutilisateur + propriétaire comme un champ, que le groupe soit présent ou non. (un exercice pour le lecteur!)

Réponse

du filename vous indiquera lutilisation du disque en octets.

Je préfère du -h filename, qui vous donne la taille dans un format lisible par lhomme.

Commentaires

  • that or stat -c "%s"😉
  • Cette saveur de du imprime la taille en blocs de 1 024 octets, pas un simple nombre doctets.
  • Notez que la norme du donne une sortie en nombre dunités de 512 octets. GNU du utilise des kibibytes à la place à moins dêtre appelé avec POSIXLY_CORRECT dans son environnement.
  • Pour les fichiers de type répertoire , qui donne lutilisation du disque du répertoire mais aussi de tous les autres fichiers à lintérieur (récursivement).

Réponse

Créez de petites fonctions utilitaires dans vos scripts shell auxquels vous pouvez déléguer.

Exemple

#! /bin/sh - # vim: set ft=sh # size utility that works on GNU and BSD systems size(){ case $(uname) in (Darwin | *BSD*) stat -Lf %z -- "$1";; (*) stat -c %s -- "$1" esac } for f do printf "%s\n" "$f : $(gzip < "$f" | wc -c) bytes (versus $(size "$f") bytes)" done 

Basé sur les informations de la réponse de @ Stéphane Chazelas « .

Commentaires

  • Voir aussi gzip -v < file > /dev/null pour vérifier la compressibilité dun fichier.
  • @St é phaneChazelas ne sait pas si je pense que cétait une amélioration. Ces déclarations de cas peuvent facilement rebuter les noobs; Je ne me souviens certainement jamais comment les faire correctement 🙂 sont des déclarations de cas par nature plus portables puisque je vois le point quand il y a plus de deux cas, mais sinon … +
  • Je suppose que ‘ est aussi une question de goût, mais ici, ‘ est le cas typique où vous ‘ voulez utiliser un case case est la construction Bourne / POSIX pour faire une correspondance de modèle. [[...]] est ksh / bash / zsh uniquement (avec des variantes).

Réponse

Jai trouvé une doublure AWK 1, et il y avait un bug mais je lai corrigé. Jai également ajouté des PetaBytes après TeraBytes.

FILE_SIZE=234234 # FILESIZE IN BYTES FILE_SIZE=$(echo "${FILE_SIZE}" | awk "{ split( "B KB MB GB TB PB" , v ); s=1; while( $1>1024 ){ $1/=1024; s++ } printf "%.2f %s", $1, v[s] }") 

Considérant stat nest pas sur tous les systèmes, vous pouvez presque toujours utiliser la solution AWK. Exemple; le Raspberry Pi na pas de stat mais il a awk .

Commentaires

  • Complètement PAS ce que lOP a demandé, mais joli petit travail.

Réponse

Jaime loption wc moi-même. Associé à « bc », vous pouvez obtenir des décimales à autant dendroits que vous le souhaitez.

Je cherchais à améliorer un script que javais qui a « édité la colonne » taille du fichier « dun » ls – alh « commande. Je ne voulais pas seulement des tailles de fichier entières, et deux décimales semblaient convenir, donc après avoir lu cette discussion, jai trouvé le code ci-dessous.

Je suggère de couper la ligne aux points-virgules si vous lincluez dans un script.

file=$1; string=$(wc -c $file); bite=${string% *}; okay=$(echo "scale=2; $bite/1024" | bc);friend=$(echo -e "$file $okay" "kb"); echo -e "$friend"

Mon Le script est appelé gpfl , pour « obtenir la longueur du fichier image ». Je lutilise après avoir fait un mogrify sur un fichier dans imagemagick, avant douvrir ou de recharger une image dans une visionneuse jpeg GUI.

Je ne sais pas comment cela est une «réponse», car elle emprunte beaucoup à ce qui a déjà été proposé et discuté. Je vais donc en rester là.

BZT

Commentaires

  • Je préférerais utiliser  » stat  » ou  » ls « . En général, ‘ jaime utiliser  » wc  » pour obtenir la taille des fichiers car il lit physiquement lintégralité du fichier. Si vous avez beaucoup de fichiers, ou des fichiers particulièrement volumineux, cela peut prendre beaucoup de temps. Mais votre solution est créative … + 1.
  • Je suis daccord avec lidée dutilisation de  » stat  » sur  » wc  » pour la taille du fichier, mais si vous utilisez  » wc -c « , aucune donnée ne sera lue; à la place, lseek sera utilisé pour déterminer le nombre doctets dans un fichier. lingrok.org/xref/coreutils/src/wc.c#228
  • @ bbaja42 : notez que GNU Coreutils lit le dernier bloc du fichier, au cas où stat.st_size nétait quune approximation (comme pour Linux /proc et /sys fichiers). Je suppose quils ont décidé de ne pas compliquer le commentaire principal quand ils ont ajouté cette logique quelques lignes plus bas: lingrok.org/xref/coreutils/src/wc.c#246

Réponse

La méthode la plus rapide et la plus simple (IMO) est:

bash_var=$(stat -c %s /path/to/filename) 

Commentaires

  • Puis votez pour une ou plusieurs des réponses existantes qui mentionnent stat; pas besoin de le répéter …
  • @JeffSchaller Je viens de voter pour la réponse de Stéphane ‘ sur vos instructions.Je pense que cest trop compliqué pour mes besoins. Cest pourquoi jai posté cette réponse simple pour les âmes partageant les mêmes idées.
  • Merci; il ‘ nest quune sixième instance dune  » stat  » answer ne ‘ t simplifie ce Q & A, mais préfère inciter un nouveau lecteur à se demander  » en quoi cette réponse est-elle différente des autres?  » et mène à plus de confusion au lieu de moins.
  • @JeffSchaller je suppose. Mais je pourrais me plaindre des nombreuses réponses du et wc qui devraient comporter une clause de non-responsabilité NE JAMAIS FAIRE CELA en réel la vie. Jai juste utilisé ma réponse dans une application réelle ce soir et jai pensé que cela valait la peine dêtre partagé. Je suppose que nous avons tous nos opinions hausse les épaules .

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *