@ hanunted85 statest la méthode la plus simple, si vous utilisez Linux ou Cygwin (ce statn'est pas standard). wc -ccomme suggéré par Eugéne est portable.
Gilles
2
stat: illegal option -- c
Iulian Onofrei
stat --printf="%s" file.txtNe donne rien sur Debian Jessie ...
woohoo
5
Sur MacOS cela fonctionne:stat -f%z myfile.tar
ccpizza
2
@woohoo Votre invite remplace la sortie. man statdit que --printf omet le retour à la ligne final. Utilisez --formatou -cpour voir la sortie. Gagnez en perspicacité en comparant stat --printf="%s" file.any | xxd -àstat -c "%s" file.any | xxd -
petit
92
file_size_kb=`du -k "$filename" | cut -f1`
Le problème de l'utilisation statest qu'il s'agit d'une extension GNU (Linux). du -ket cut -f1sont spécifiés par POSIX et sont donc portables sur tout système Unix.
Solaris, par exemple, est livré avec bash mais pas avec stat. Donc, ce n'est pas entièrement hypothétique.
lsLe problème est similaire: le format exact de la sortie n’est pas spécifié. Par conséquent, l’analyse de la sortie ne peut pas être effectuée de manière portable. du -hest aussi une extension GNU.
Si possible, respectez les constructions portables et vous faciliterez la vie de quelqu'un à l'avenir. Peut-être la vôtre.
dune donne pas la taille du fichier, mais donne une indication de la quantité d’espace utilisé par le fichier, ce qui est légèrement différent (généralement, la taille indiquée par duest la taille du fichier arrondie au nombre de blocs le plus proche, où un bloc est typiquement 512B ou 1KB ou 4KB).
Gilles le
7
@Gilles, les fichiers clairsemés (c'est-à-dire ceux comportant des trous) indiquent une longueur inférieure à la longueur.
vonbrand
5
Ceci, avec --bytesou -bau lieu de -k, devrait être la réponse acceptée.
Amédée Van Gasse le
1
L' -hoption ("humaine") dedu produira la réponse la plus appropriée pour les cas généraux:, file_size=`du -h "$filename" | cut -f1car elle affichera K (kilo-octets), M (mégaoctets) ou G (gigaoctets) selon le cas.
Fralau
1
@fralau: Le PO veut "assigner cela à une variable bash pour pouvoir l'utiliser plus tard", il est donc beaucoup plus probable qu'il veuille une valeur numérique réelle, et non une approximation lisible par l'homme. En outre, -hest une extension GNU; ce n'est pas la norme
Nemo
74
Vous pouvez également utiliser la commande "nombre de mots" ( wc):
wc -c "$filename"| awk '{print $1}'
Le problème avec wcest qu'il va ajouter le nom de fichier et indenter la sortie. Par exemple:
$ wc -c somefile.txt1160 somefile.txt
Si vous souhaitez éviter de chaîner un langage interprété complet ou un éditeur de flux uniquement pour obtenir un décompte de la taille du fichier, redirigez simplement l'entrée du fichier afin que wcle nom de fichier ne soit jamais visible:
wc -c <"$filename"
Cette dernière forme peut être utilisée avec la substitution de commande pour saisir facilement la valeur recherchée en tant que variable shell, comme mentionné par Gilles ci-dessous.
wc -c <"$FILENAME"donne la taille sans autre crue, donc size=$(wc -c <"$FILENAME").
Gilles
6
Encore un point: je viens de le tester et wc -c < filesemble être très rapide, du moins sous OS X. J'imagine que wc a le cerveau pour essayer de stater le fichier si seulement -c est spécifié.
Edward Falk
4
@ EdwardFalk: GNU wc -cutilise fstat, mais cherche ensuite à l'avant dernier bloc du fichier et lit les derniers st_blksizeoctets. Apparemment , c'est parce que les fichiers de Linux /procet /syspar exemple ont des tailles de stat qui ne sont approximatifs , et wcveut faire rapport à la taille réelle, pas la taille indiquée stat. J'imagine que ce serait bizarre wc -cde signaler une taille différente de wc, mais ce n'est pas une idée de lire les données du fichier s'il s'agit d'un fichier de disque normal, et ce n'est pas en mémoire. Ou pire, stockage sur bande proche de la ligne ...
Peter Cordes
1
Il semble que printfl’indentation est toujours visible, par exemple printf "Size: $size"-> size: <4 spaces> 54339. D'autre part echoignore les espaces blancs. Un moyen de le rendre cohérent?
Eugene Kulabuhov
2
@keithpjolley: En appelant fstat. Essayez de courir strace wc -c </etc/passwdet vous pouvez voir ce qu'il fait.
Nemo le
48
Les BSD (Mac OS X) statont un indicateur d'argument de format différent et des spécificateurs de champ différents. De man stat(1):
-f format: Affiche des informations en utilisant le format spécifié. Voir la section FORMATS pour une description des formats valides.
vous donnera le nombre d'octets pouvant être lus dans le fichier. IOW, c'est la taille du contenu du fichier. Cependant, le contenu du fichier sera lu (sauf s'il s'agit d'un fichier normal ou d'un lien symbolique vers un fichier normal dans la plupart des wcimplémentations, à titre d'optimisation). Cela peut avoir des effets secondaires. Par exemple, pour un canal nommé, ce qui a été lu ne peut plus être lu à nouveau et pour des choses comme /dev/zeroou /dev/randomqui sont de taille infinie, cela va prendre un certain temps. Cela signifie également que vous avez besoin d'une readautorisation pour le fichier et que le dernier horodatage d'accès au fichier peut être mis à jour.
C'est standard et portable, mais notez que certaines wcimplémentations peuvent inclure des blancs non significatifs dans cette sortie. Une façon de s'en débarrasser est d'utiliser:
size=$(($(wc -c <"$file")))
ou pour éviter une erreur sur une expression arithmétique vide dans dashou yashquand wcne produit aucune sortie (comme lorsque le fichier ne peut pas être ouvert):
size=$(($(wc -c <"$file")+0))
ksh93a wcintégré (à condition de l'activer, vous pouvez également l'invoquer comme command /opt/ast/bin/wc), ce qui en fait le moyen le plus efficace pour les fichiers normaux de ce shell.
Différents systèmes ont une commande appelée statinterface permettant d’ appeler le stat()ou les lstat()appels système.
Ceux-ci rapportent des informations trouvées dans l'inode. L'une de ces informations est l' st_sizeattribut. Pour les fichiers normaux, c'est la taille du contenu (combien de données pourraient être lues en l'absence d'erreur (c'est ce que la plupart des wc -cimplémentations utilisent dans leur optimisation)). Pour les liens symboliques, il s'agit de la taille en octets du chemin cible. Pour les canaux nommés, selon le système, il s'agit de 0 ou du nombre d'octets actuellement dans le tampon de canal. Idem pour les périphériques en mode bloc où, selon le système, vous obtenez 0 ou la taille en octets du stockage sous-jacent.
Vous n'avez pas besoin d'une autorisation de lecture sur le fichier pour obtenir ces informations, vous devez uniquement rechercher une autorisation d'accès au répertoire auquel il est lié.
stat -f %z --"$file"# st_size of file
stat -Lf%z --"$file"# after symlink resolution
Ou vous pouvez utiliser la fonction stat()/ lstat()de certains langages de script tels que perl:
perl -le 'print((lstat shift)[7])'--"$file"
AIX propose également une istatcommande qui dumpe toutes les informations stat()( lstat()qui ne fonctionneront pas , cela ne fonctionnera pas sur les liens symboliques) et avec lesquelles vous pourriez post-traiter, par exemple:
Bien avant que GNU n'introduise sa statcommande, la même chose pouvait être obtenue avec la findcommande GNU avec son -printfprédicat (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 cependant est que cela ne fonctionne pas si $filecommence avec -ou est un findprédicat (comme !, (...).
La commande standard pour obtenir les informations stat()/ lstat()est ls.
POSIXly, vous pouvez faire:
LC_ALL=C ls -dn --"$file"| awk '{print $5; exit}'
et ajouter -Lpour la même après la résolution de lien symbolique. Cela ne fonctionne pas pour les fichiers de périphérique où le 5ème champ est le numéro majeur de périphérique au lieu de la taille.
Pour les périphériques en mode bloc, les systèmes où la valeur stat()0 est retournée st_sizeont généralement d'autres API pour indiquer la taille du périphérique en bloc. Par exemple, Linux a le BLKGETSIZE64ioctl(), et la plupart des distributions Linux sont maintenant livrées avec une blockdevcommande qui peut s’en servir:
blockdev --getsize64 --"$device_file"
Cependant, vous avez besoin d'une autorisation de lecture sur le fichier de périphérique pour cela. Il est généralement possible de calculer la taille par d'autres 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 pouvant être recherchés (inclut donc les fichiers normaux, la plupart des périphériques en mode bloc et certains périphériques avec des caractères) consiste à ouvrir le fichier et à rechercher jusqu'à la fin:
Avec zsh(après chargement du zsh/systemmodule):
{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 pipes nommés, nous avons vu que certains systèmes (AIX, Solaris, HP / UX au moins) font la quantité de données dans le tampon de tube disponible dans stat()« s st_size. Certains (comme Linux ou FreeBSD) ne le font pas.
Sous Linux au moins, vous pouvez utiliser le FIONREADioctl()code après avoir ouvert le tuyau (en mode lecture + écriture pour éviter tout blocage):
Cependant, notez que bien que le contenu du tuyau ne soit pas lu , la simple ouverture du tuyau nommé ici peut toujours avoir des effets secondaires. Nous fuservérifions d’abord que certains processus sont déjà ouverts, mais ce n’est pas infaillible, car fuserils ne pourront peut-être pas vérifier tous les processus.
Jusqu'à présent, nous n'avons pris en compte que la taille des données primaires associées aux fichiers. Cela ne tient pas compte de la taille des métadonnées et de toute l'infrastructure requise pour stocker ce fichier.
Un autre attribut inode renvoyé par stat()is st_blocks. C'est 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). Cela n'inclut pas l'inode lui-même ni les entrées des répertoires auxquels le fichier est lié.
La taille et l'utilisation du disque ne sont pas nécessairement étroitement liées: compression, faible densité (parfois quelques métadonnées), une infrastructure supplémentaire telle que les blocs indirects dans certains systèmes de fichiers ont une influence sur ce dernier.
C'est généralement ce qui duutilise pour signaler l'utilisation du disque. La plupart des commandes répertoriées ci-dessus pourront vous fournir cette information.
POSIXLY_CORRECT=1 ls -sd -- "$file" | awk '{print $1; exit}'
POSIXLY_CORRECT=1 du -s -- "$file" (pas pour les répertoires où cela inclurait l'utilisation du disque des fichiers à l'intérieur).
clairement la réponse la plus complète et informative. Merci. Je peux l'utiliser pour créer des scripts bash multi-plateformes à l'aide des informations statistiques BSD et GNU
ce travail ne serait pas tropls -go file | awk '{print $3}'
Steven Penny
@StevenPenny, ceux-ci -goseraient ceux de SysV, ils ne fonctionneraient pas sur les BSD (optionnel (XSI) dans POSIX). Vous aurez également besoin de ls -god file | awk '{print $3; exit}'( -dpour que cela fonctionne sur les répertoires, exitpour les liens symboliques avec des lignes nouvelles dans la cible). Les problèmes avec les fichiers de périphérique demeurent également.
Stéphane Chazelas
1
@ αғsнιη L'API Unix ne fait aucune distinction entre les fichiers texte et les fichiers binaires. Ce sont toutes des séquences d'octets. Certaines applications peuvent vouloir interpréter ces octets sous forme de texte, mais évidemment pas pour wc -cindiquer le nombre d'octets.
Stéphane Chazelas
22
Ce script combine plusieurs manières de calculer la taille du fichier:
Le script fonctionne sur de nombreux systèmes Unix, notamment Linux, BSD, OSX, Solaris, SunOS, etc.
La taille du fichier indique le nombre d'octets. C'est la taille apparente, c'est-à-dire les octets que le fichier utilise sur un disque typique, sans compression spéciale, ni zones clairsemées spéciales, ni blocs non alloués, etc.
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 l'exemple ci-dessous, la taille du fichier est juste en dessous de 2 Ko:
-rw-r--r--1 user owner 19852011-07-1216:48 index.php
Edit: Ce n'est apparemment pas aussi fiable que la statcommande.
Je pense que les deux ls -let statprescris donner des informations de taille fiable. Je n'ai trouvé aucune référence au contraire. ls -sdonnera la taille en nombre de blocs.
dabest1
2
@ dabest1 ce n'est pas fiable dans un sens que dans un autre unix, leur sortie peut être différente (et dans certains unix, c'est le cas).
Eugene Bujak
Oui, IIRC, Solaris n’affiche pas le nom du groupe par défaut, ce qui entraîne moins de colonnes dans la sortie.
Edward Falk
Puisque la taille est purement numérique, entourée d'espaces, et que l'année de la date est purement numérique, dans un format défini, il serait possible d'utiliser une expression rationnelle pour traiter l'utilisateur + propriétaire comme un seul champ, que le groupe soit présent ou non. (Un exercice pour le lecteur!)
MikeW
5
du filename vous dira l'utilisation du disque en octets.
Je préfère du -h filename, ce qui vous donne la taille dans un format lisible par l'homme.
Cette variété d' duimprimés taille en blocs de 1024 octets et non en un simple décompte d'octets.
Peter Lyons
Notez que standard dudonne une sortie en nombre d'unités de 512 octets. GNU duutilise des kilo-octets à la place, sauf s’il est appelé avec POSIXLY_CORRECTdans son environnement.
Stéphane Chazelas
1
Pour les fichiers de type répertoire , cela donne l'utilisation du disque du répertoire mais également de tous les autres fichiers qu'il contient (de manière récursive).
Stéphane Chazelas
3
Créez de petites fonctions utilitaires dans vos scripts de shell auxquelles 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 @ Stéphane Chazelas 'answer.
Voir aussi gzip -v < file > /dev/nullpour vérifier la compressibilité d'un fichier.
Stéphane Chazelas
@ StéphaneChazelas pas sûr si je pense que c'était une amélioration. ces déclarations de cas peuvent facilement mettre noobs off; Je ne me souviens certainement jamais comment les corriger :-) Les déclarations de cas sont-elles intrinsèquement plus faciles à transporter depuis que vous les avez faites? Je vois le point où il y a plus de deux cas, mais sinon ... +
oligofren
1
Je suppose que c'est aussi une question de goût, mais ici, c'est le cas typique où vous voudriez utiliser une casedéclaration. caseest la construction Bourne / POSIX pour faire la correspondance de modèle. [[...]]ksh / bash / zsh est seulement (avec des variations).
Stéphane Chazelas
2
J'ai trouvé un paquebot AWK 1 et il y avait un bug mais je l'ai corrigé. J'ai également ajouté dans PetaBytes après TeraBytes.
Étant donné que stat ne figure pas sur tous les systèmes, vous pouvez presque toujours utiliser la solution AWK. Exemple; le Raspberry Pi n'a pas de stat mais il a un awk .
Complètement PAS ce que le PO a demandé, mais bon petit travail.
Gypsy Spellweaver
0
Un autre moyen compatible POSIX serait d'utiliser awkavec sa length()fonction qui retourne la longueur, en caractères sur chaque ligne du fichier d'entrée, à l'exclusion des caractères de nouvelle ligne. Donc en faisant
awk '{ sum+=length } END { print sum+NR }' file
nous nous assurons que NRsoit ajouté à sum, ce qui donne le nombre total de caractères et le nombre total de nouvelles lignes rencontrées dans le fichier. La length()fonction in awkprend un argument qui, par défaut, length($0)correspond à la ligne entière courante.
Pas si la dernière ligne ne se termine pas sur une nouvelle ligne: printf 'a\nb' | awk '{ sum+=length } END { print sum+NR }'doit imprimer 3 mais en imprimer 4.
Isaac
-1
J'aime l'option wc moi-même. Jumelé avec 'bc', vous pouvez obtenir des décimales dans autant d'endroits que vous le souhaitez.
Je cherchais à améliorer un script que j'avais créé avec la colonne "taille du fichier" d'une commande "ls -alh". Je ne voulais pas seulement des tailles de fichier entières, et deux décimales semblaient convenir, alors après avoir lu cette discussion, j'ai proposé le code ci-dessous.
Je suggère de rompre la ligne au point-virgule si vous l'incluez dans un script.
Mon script s'appelle gpfl , pour "obtenir la longueur du fichier image". Je l'utilise après avoir fait un mogrifier sur un fichier dans imagemagick, avant d'ouvrir ou de recharger une image dans une visionneuse jpeg GUI.
Je ne sais pas comment cela constitue une "réponse", car il emprunte beaucoup à ce qui a déjà été proposé et discuté. Donc je vais le laisser là.
Je préférerais utiliser "stat" ou "ls". En général, je n'aime pas utiliser "wc" pour obtenir la taille des fichiers, car il lit physiquement l'inté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.
Kevin Fegan
2
Je suis d'accord avec l'idée d'utiliser "stat" sur "wc" pour la taille du fichier, cependant si vous utilisez "wc -c", aucune donnée ne sera lue; Au lieu de cela, lseek sera utilisé pour déterminer le nombre d'octets dans un fichier. lingrok.org/xref/coreutils/src/wc.c#228
bbaja42
1
@ bbaja42: notez que GNU Coreutils wclit le dernier bloc du fichier, au cas où ce stat.st_sizene serait qu'une approximation (comme pour Linux /procet les /sysfichiers). Je suppose qu'ils ont décidé de ne pas faire le principal commentaire plus compliqué quand ils ont ajouté que la logique quelques lignes vers le bas: lingrok.org/xref/coreutils/src/wc.c#246
Peter Cordes
-1
La méthode la plus rapide et la plus simple (IMO) est la suivante:
Puis invectez une ou plusieurs des réponses existantes qui mentionnent stat; nul besoin de le répéter encore une fois ...
Jeff Schaller
1
@JeffSchaller Je viens de voter pour la réponse de Stéphane sur vos instructions. Je pense que c'est trop compliqué pour mes objectifs. C'est pourquoi j'ai posté cette réponse simple pour des âmes partageant les mêmes idées.
WinEunuuchs2Unix
1
Je vous remercie; c'est simplement qu'une sixième instance d'une réponse "stat" ne simplifie pas cette Q & A, mais qu'elle se fasse demander à un nouveau lecteur de se demander "en quoi cette réponse est-elle différente des autres?" et conduire à plus de confusion au lieu de moins.
Jeff Schaller
@ JeffSchaller je suppose. Mais je pourrais me plaindre du nombre duet des wcréponses qui devraient avoir une mise en garde Ne jamais faire cela dans la vie réelle. Je viens d'utiliser ma réponse dans une application réelle ce soir et je pensais que cela valait la peine d'être partagé. Je suppose que nous avons tous nos opinions haussements d'épaules .
pv
etcat
pour une commande de copie qui montre le progrès et l' ETA :)Réponses:
Votre meilleur pari si sur un système GNU:
De l' homme stat :
Dans un script bash:
REMARQUE: voir la réponse de @ chbrown pour savoir comment utiliser stat dans un terminal sous Mac OS X.
la source
stat
est la méthode la plus simple, si vous utilisez Linux ou Cygwin (cestat
n'est pas standard).wc -c
comme suggéré par Eugéne est portable.stat: illegal option -- c
stat --printf="%s" file.txt
Ne donne rien sur Debian Jessie ...stat -f%z myfile.tar
man stat
dit que --printf omet le retour à la ligne final. Utilisez--format
ou-c
pour voir la sortie. Gagnez en perspicacité en comparantstat --printf="%s" file.any | xxd -
àstat -c "%s" file.any | xxd -
Le problème de l'utilisation
stat
est qu'il s'agit d'une extension GNU (Linux).du -k
etcut -f1
sont spécifiés par POSIX et sont donc portables sur tout système Unix.Solaris, par exemple, est livré avec bash mais pas avec
stat
. Donc, ce n'est pas entièrement hypothétique.ls
Le problème est similaire: le format exact de la sortie n’est pas spécifié. Par conséquent, l’analyse de la sortie ne peut pas être effectuée de manière portable.du -h
est aussi une extension GNU.Si possible, respectez les constructions portables et vous faciliterez la vie de quelqu'un à l'avenir. Peut-être la vôtre.
la source
du
ne donne pas la taille du fichier, mais donne une indication de la quantité d’espace utilisé par le fichier, ce qui est légèrement différent (généralement, la taille indiquée pardu
est la taille du fichier arrondie au nombre de blocs le plus proche, où un bloc est typiquement 512B ou 1KB ou 4KB).--bytes
ou-b
au lieu de-k
, devrait être la réponse acceptée.-h
option ("humaine") dedu
produira la réponse la plus appropriée pour les cas généraux:,file_size=`du -h "$filename" | cut -f1
car elle affichera K (kilo-octets), M (mégaoctets) ou G (gigaoctets) selon le cas.-h
est une extension GNU; ce n'est pas la normeVous pouvez également utiliser la commande "nombre de mots" (
wc
):Le problème avec
wc
est qu'il va ajouter le nom de fichier et indenter la sortie. Par exemple:Si vous souhaitez éviter de chaîner un langage interprété complet ou un éditeur de flux uniquement pour obtenir un décompte de la taille du fichier, redirigez simplement l'entrée du fichier afin que
wc
le nom de fichier ne soit jamais visible:Cette dernière forme peut être utilisée avec la substitution de commande pour saisir facilement la valeur recherchée en tant que variable shell, comme mentionné par Gilles ci-dessous.
la source
wc -c <"$FILENAME"
donne la taille sans autre crue, doncsize=$(wc -c <"$FILENAME")
.wc -c < file
semble être très rapide, du moins sous OS X. J'imagine que wc a le cerveau pour essayer de stater le fichier si seulement -c est spécifié.wc -c
utilisefstat
, mais cherche ensuite à l'avant dernier bloc du fichier et lit les derniersst_blksize
octets. Apparemment , c'est parce que les fichiers de Linux/proc
et/sys
par exemple ont des tailles de stat qui ne sont approximatifs , etwc
veut faire rapport à la taille réelle, pas la taille indiquée stat. J'imagine que ce serait bizarrewc -c
de signaler une taille différente dewc
, mais ce n'est pas une idée de lire les données du fichier s'il s'agit d'un fichier de disque normal, et ce n'est pas en mémoire. Ou pire, stockage sur bande proche de la ligne ...printf
l’indentation est toujours visible, par exempleprintf "Size: $size"
->size: <4 spaces> 54339
. D'autre partecho
ignore les espaces blancs. Un moyen de le rendre cohérent?fstat
. Essayez de courirstrace wc -c </etc/passwd
et vous pouvez voir ce qu'il fait.Les BSD (Mac OS X)
stat
ont un indicateur d'argument de format différent et des spécificateurs de champ différents. Deman stat(1)
:-f format
: Affiche des informations en utilisant le format spécifié. Voir la section FORMATS pour une description des formats valides.z
: La taille du fichier en octets.Alors tous ensemble maintenant:
la source
Cela dépend de ce que vous entendez par taille .
vous donnera le nombre d'octets pouvant être lus dans le fichier. IOW, c'est la taille du contenu du fichier. Cependant, le contenu du fichier sera lu (sauf s'il s'agit d'un fichier normal ou d'un lien symbolique vers un fichier normal dans la plupart des
wc
implémentations, à titre d'optimisation). Cela peut avoir des effets secondaires. Par exemple, pour un canal 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 d'uneread
autorisation pour le fichier et que le dernier horodatage d'accès au fichier peut être mis à jour.C'est standard et portable, mais notez que certaines
wc
implémentations peuvent inclure des blancs non significatifs dans cette sortie. Une façon de s'en débarrasser est d'utiliser:ou pour éviter une erreur sur une expression arithmétique vide dans
dash
ouyash
quandwc
ne produit aucune sortie (comme lorsque le fichier ne peut pas être ouvert):ksh93
awc
intégré (à condition de l'activer, vous pouvez également l'invoquer commecommand /opt/ast/bin/wc
), ce qui en fait le moyen le plus efficace pour les fichiers normaux de ce shell.Différents systèmes ont une commande appelée
stat
interface permettant d’ appeler lestat()
ou leslstat()
appels système.Ceux-ci rapportent des informations trouvées dans l'inode. L'une de ces informations est l'
st_size
attribut. Pour les fichiers normaux, c'est la taille du contenu (combien de données pourraient être lues en l'absence d'erreur (c'est ce que la plupart deswc -c
implémentations utilisent dans leur optimisation)). Pour les liens symboliques, il s'agit de la taille en octets du chemin cible. Pour les canaux nommés, selon le système, il s'agit de 0 ou du nombre d'octets actuellement dans le tampon de canal. Idem pour les périphériques en mode bloc où, selon le système, vous obtenez 0 ou la taille en octets du stockage sous-jacent.Vous n'avez pas besoin d'une autorisation de lecture sur le fichier pour obtenir ces informations, vous devez uniquement rechercher une autorisation d'accès au répertoire auquel il est lié.
Par ordre chronologique, il y a:
IRIX
stat
(90's):renvoie l'
st_size
attribut de$file
(lstat()
) ou:idem sauf lorsqu'il
$file
s'agit d'un lien symbolique, auquel cas il s'agitst_size
du fichier après la résolution du lien symbolique.zsh
stat
intégré (maintenant aussi appelézstat
) dans lezsh/stat
module (chargé aveczmodload zsh/stat
) (1997):ou pour stocker dans une variable:
évidemment, c'est le plus efficace dans cette coquille.
GNU
stat
(2001); également dans BusyBoxstat
depuis 2005 (copie de GNUstat
):(notez que la signification de
-L
est inversée par rapport à IRIX ouzsh
stat
.BSD
stat
(2002):Ou vous pouvez utiliser la fonction
stat()
/lstat()
de certains langages de script tels queperl
:AIX propose également une
istat
commande qui dumpe toutes les informationsstat()
(lstat()
qui ne fonctionneront pas , cela ne fonctionnera pas sur les liens symboliques) et avec lesquelles vous pourriez post-traiter, par exemple:(Merci @JeffSchaller pour l' aide à la définition des détails ).
Dans
tcsh
:(taille après résolution du lien symbolique)
Bien avant que GNU n'introduise sa
stat
commande, la même chose pouvait être obtenue avec lafind
commande GNU avec son-printf
prédicat (déjà en 1991):Un problème cependant est que cela ne fonctionne pas si
$file
commence avec-
ou est unfind
prédicat (comme!
,(
...).La commande standard pour obtenir les informations
stat()
/lstat()
estls
.POSIXly, vous pouvez faire:
et ajouter
-L
pour la même après la résolution de lien symbolique. Cela ne fonctionne pas pour les fichiers de périphérique où le 5ème champ est le numéro majeur de périphérique au lieu de la taille.Pour les périphériques en mode bloc, les systèmes où la valeur
stat()
0 est retournéest_size
ont généralement d'autres API pour indiquer la taille du périphérique en bloc. Par exemple, Linux a leBLKGETSIZE64
ioctl()
, et la plupart des distributions Linux sont maintenant livrées avec uneblockdev
commande qui peut s’en servir:Cependant, vous avez besoin d'une autorisation de lecture sur le fichier de périphérique pour cela. Il est généralement possible de calculer la taille par d'autres moyens. Par exemple (toujours sous Linux):
Devrait fonctionner sauf pour les appareils vides.
Une approche qui fonctionne pour tous les fichiers pouvant être recherchés (inclut donc les fichiers normaux, la plupart des périphériques en mode bloc et certains périphériques avec des caractères) consiste à ouvrir le fichier et à rechercher jusqu'à la fin:
Avec
zsh
(après chargement duzsh/system
module):Avec
ksh93
:ou
avec
perl
:Pour les pipes nommés, nous avons vu que certains systèmes (AIX, Solaris, HP / UX au moins) font la quantité de données dans le tampon de tube disponible dans
stat()
« sst_size
. Certains (comme Linux ou FreeBSD) ne le font pas.Sous Linux au moins, vous pouvez utiliser le
FIONREAD
ioctl()
code après avoir ouvert le tuyau (en mode lecture + écriture pour éviter tout blocage):Cependant, notez que bien que le contenu du tuyau ne soit pas lu , la simple ouverture du tuyau nommé ici peut toujours avoir des effets secondaires. Nous
fuser
vérifions d’abord que certains processus sont déjà ouverts, mais ce n’est pas infaillible, carfuser
ils ne pourront peut-être pas vérifier tous les processus.Jusqu'à présent, nous n'avons pris en compte que la taille des données primaires associées aux fichiers. Cela ne tient pas compte de la taille des métadonnées et de toute l'infrastructure requise pour stocker ce fichier.
Un autre attribut inode renvoyé par
stat()
isst_blocks
. C'est 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). Cela n'inclut pas l'inode lui-même ni les entrées des répertoires auxquels le fichier est lié.La taille et l'utilisation du disque ne sont pas nécessairement étroitement liées: compression, faible densité (parfois quelques métadonnées), une infrastructure supplémentaire telle que les blocs indirects dans certains systèmes de fichiers ont une influence sur ce dernier.
C'est généralement ce qui
du
utilise pour signaler l'utilisation du disque. La plupart des commandes répertoriées ci-dessus pourront vous fournir cette information.POSIXLY_CORRECT=1 ls -sd -- "$file" | awk '{print $1; exit}'
POSIXLY_CORRECT=1 du -s -- "$file"
(pas pour les répertoires où cela inclurait l'utilisation du disque des fichiers à l'intérieur).find -- "$file" -printf '%b\n'
zstat -L +block -- $file
stat -c %b -- "$file"
stat -f %b -- "$file"
perl -le 'print((lstat shift)[12])' -- "$file"
la source
wc -c
utilisefstat
, mais lit ensuite les derniersst_blksize
octets. Apparemment, cela est dû au fait que les fichiers sous Linux/proc
et/sys
par exemple ont des tailles de statistiques approximatives . C'est bon pour l'exactitude, mais mauvais si la fin du fichier est sur le disque et non en mémoire (surtout si elle est utilisée sur plusieurs fichiers en boucle). Et très mauvais si le fichier est migré vers un stockage sur bande proche de la ligne , ou par exemple un système de fichiers FUSE à décompression transparente.ls -go file | awk '{print $3}'
-go
seraient ceux de SysV, ils ne fonctionneraient pas sur les BSD (optionnel (XSI) dans POSIX). Vous aurez également besoin dels -god file | awk '{print $3; exit}'
(-d
pour que cela fonctionne sur les répertoires,exit
pour les liens symboliques avec des lignes nouvelles dans la cible). Les problèmes avec les fichiers de périphérique demeurent également.wc -c
indiquer le nombre d'octets.Ce script combine plusieurs manières de calculer la taille du fichier:
Le script fonctionne sur de nombreux systèmes Unix, notamment Linux, BSD, OSX, Solaris, SunOS, etc.
La taille du fichier indique le nombre d'octets. C'est la taille apparente, c'est-à-dire les octets que le fichier utilise sur un disque typique, sans compression spéciale, ni zones clairsemées spéciales, ni blocs non alloués, etc.
Ce script a une version de production avec plus d'aide et plus d'options ici: https://github.com/SixArm/file-size
la source
stat semble le faire avec le moins d'appels système:
la source
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 l'exemple ci-dessous, la taille du fichier est juste en dessous de 2 Ko:
Edit: Ce n'est apparemment pas aussi fiable que la
stat
commande.la source
ls -l
etstat
prescris donner des informations de taille fiable. Je n'ai trouvé aucune référence au contraire.ls -s
donnera la taille en nombre de blocs.du filename
vous dira l'utilisation du disque en octets.Je préfère
du -h filename
, ce qui vous donne la taille dans un format lisible par l'homme.la source
stat -c "%s"
;)du
imprimés taille en blocs de 1024 octets et non en un simple décompte d'octets.du
donne une sortie en nombre d'unités de 512 octets. GNUdu
utilise des kilo-octets à la place, sauf s’il est appelé avecPOSIXLY_CORRECT
dans son environnement.Créez de petites fonctions utilitaires dans vos scripts de shell auxquelles vous pouvez déléguer.
Exemple
Basé sur les informations de @ Stéphane Chazelas 'answer.
la source
gzip -v < file > /dev/null
pour vérifier la compressibilité d'un fichier.case
déclaration.case
est la construction Bourne / POSIX pour faire la correspondance de modèle.[[...]]
ksh / bash / zsh est seulement (avec des variations).J'ai trouvé un paquebot AWK 1 et il y avait un bug mais je l'ai corrigé. J'ai également ajouté dans PetaBytes après TeraBytes.
Étant donné que stat ne figure pas sur tous les systèmes, vous pouvez presque toujours utiliser la solution AWK. Exemple; le Raspberry Pi n'a pas de stat mais il a un awk .
la source
Un autre moyen compatible POSIX serait d'utiliser
awk
avec salength()
fonction qui retourne la longueur, en caractères sur chaque ligne du fichier d'entrée, à l'exclusion des caractères de nouvelle ligne. Donc en faisantnous nous assurons que
NR
soit ajouté àsum
, ce qui donne le nombre total de caractères et le nombre total de nouvelles lignes rencontrées dans le fichier. Lalength()
fonction inawk
prend un argument qui, par défaut,length($0)
correspond à la ligne entière courante.la source
printf 'a\nb' | awk '{ sum+=length } END { print sum+NR }'
doit imprimer 3 mais en imprimer 4.J'aime l'option wc moi-même. Jumelé avec 'bc', vous pouvez obtenir des décimales dans autant d'endroits que vous le souhaitez.
Je cherchais à améliorer un script que j'avais créé avec la colonne "taille du fichier" d'une commande "ls -alh". Je ne voulais pas seulement des tailles de fichier entières, et deux décimales semblaient convenir, alors après avoir lu cette discussion, j'ai proposé le code ci-dessous.
Je suggère de rompre la ligne au point-virgule si vous l'incluez 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 script s'appelle gpfl , pour "obtenir la longueur du fichier image". Je l'utilise après avoir fait un mogrifier sur un fichier dans imagemagick, avant d'ouvrir ou de recharger une image dans une visionneuse jpeg GUI.
Je ne sais pas comment cela constitue une "réponse", car il emprunte beaucoup à ce qui a déjà été proposé et discuté. Donc je vais le laisser là.
BZT
la source
wc
lit le dernier bloc du fichier, au cas où cestat.st_size
ne serait qu'une approximation (comme pour Linux/proc
et les/sys
fichiers). Je suppose qu'ils ont décidé de ne pas faire le principal commentaire plus compliqué quand ils ont ajouté que la logique quelques lignes vers le bas: lingrok.org/xref/coreutils/src/wc.c#246La méthode la plus rapide et la plus simple (IMO) est la suivante:
la source
du
et deswc
réponses qui devraient avoir une mise en garde Ne jamais faire cela dans la vie réelle. Je viens d'utiliser ma réponse dans une application réelle ce soir et je pensais que cela valait la peine d'être partagé. Je suppose que nous avons tous nos opinions haussements d'épaules .