Comment puis-je obtenir la taille dun fichier dans un script bash?
Comment attribuer ceci à une variable bash pour pouvoir lutiliser plus tard?
Commentaires
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 comparantstat --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 pardu
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, doncsize=$(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
utilisefstat
, 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 , etwc
souhaite indiquer la taille réelle, pas la taille indiquée par les statistiques. Je suppose que ce serait bizarre pourwc -c
de signaler une taille différente dewc
, 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 exempleprintf "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écuterstrace 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 lest_size
du fichier après la résolution du lien symbolique. -
zsh
stat
builtin (désormais également appelézstat
) dans le modulezsh/stat
(chargé aveczmodload 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 BusyBoxstat
depuis 2 005 (copié depuis GNUstat
):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 ouzsh
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 modulezsh/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
utilisefstat
, 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 dels -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
etstat
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. GNUdu
utilise des kibibytes à la place à moins dêtre appelé avecPOSIXLY_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
etwc
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 .
pv
etcat
pour une commande de copie indiquant la progression et lETA 🙂-s
, vous pouvez donc simplement tester si un fichier a une longueur différente de zéro avecif [ -s file ]; then echo "file has nonzero size" ; fi