@ haunted85 statist der einfachste Weg, vorausgesetzt, Sie verwenden Linux oder Cygwin ( statnicht Standard). wc -cwie von Eugéne vorgeschlagen, ist portabel.
Gilles
2
stat: illegal option -- c
Iulian Onofrei
stat --printf="%s" file.txtgibt nichts auf Debian Jessie aus ...
woohoo
5
Unter MacOS funktioniert dies wie stat -f%z myfile.tar
folgt
2
@woohoo Ihre Eingabeaufforderung überschreibt die Ausgabe. man statsagt, dass --printf die nachfolgende Newline weglässt. Verwenden Sie --formatoder -c, um die Ausgabe anzuzeigen. Gewinnen Sie mehr Einsicht im Vergleich stat --printf="%s" file.any | xxd -zustat -c "%s" file.any | xxd -
Enkelkind
92
file_size_kb=`du -k "$filename" | cut -f1`
Das Problem bei der Verwendung statist, dass es sich um eine GNU (Linux) -Erweiterung handelt. du -kund cut -f1werden von POSIX spezifiziert und sind daher auf jedes Unix-System portierbar.
Solaris wird zum Beispiel mit bash ausgeliefert, aber nicht mit stat. Das ist also nicht ganz hypothetisch.
lsEin ähnliches Problem besteht darin, dass das genaue Format der Ausgabe nicht angegeben ist, sodass das Parsen der Ausgabe nicht portabel durchgeführt werden kann. du -hist auch eine GNU-Erweiterung.
Wenn möglich, halten Sie sich an tragbare Konstrukte und Sie werden das Leben von jemandem in Zukunft einfacher machen. Vielleicht deine eigene.
dugibt nicht die Größe der Datei an, sondern gibt einen Hinweis darauf, wie viel Speicherplatz die Datei belegt, was sich geringfügig unterscheidet (normalerweise duist die angegebene Größe die Größe der Datei, aufgerundet auf die nächste Anzahl von Blöcken, bei denen ein Block vorhanden ist beträgt typischerweise 512B oder 1kB oder 4kB).
Gilles
7
@Gilles, spärliche Dateien (dh Dateien mit Löchern) geben weniger als die Länge an.
Vonbrand
5
Dies sollte mit --bytesoder -banstelle von -kdie akzeptierte Antwort sein.
Amedee Van Gasse
1
Die -hOption ("Mensch") vondu liefert die am besten geeignete Antwort für allgemeine Fälle file_size=`du -h "$filename" | cut -f1:, da K (Kilobyte), M (Megabyte) oder G (Gigabyte) angezeigt werden.
Fralau
1
@fralau: Das OP möchte "dies einer Bash-Variablen zuweisen, damit sie es später verwenden können", daher ist es viel wahrscheinlicher, dass sie einen tatsächlichen numerischen Wert und keine vom Menschen lesbare Näherung wünschen. Ist auch -heine GNU-Erweiterung; Es ist nicht Standard
Nemo
74
Sie können auch den Befehl "word count" ( wc) verwenden:
wc -c "$filename"| awk '{print $1}'
Das Problem dabei wcist, dass der Dateiname hinzugefügt und die Ausgabe eingerückt wird. Zum Beispiel:
$ wc -c somefile.txt1160 somefile.txt
Wenn Sie vermeiden möchten, einen vollständig interpretierten Sprach- oder Stream-Editor zu verketten, um die Dateigröße zu ermitteln, leiten Sie einfach die Eingabe aus der Datei um, sodass wcder Dateiname nicht angezeigt wird:
wc -c <"$filename"
Diese letzte Form kann mit der Befehlsersetzung verwendet werden, um den gesuchten Wert als Shell-Variable zu erfassen, wie von Gilles unten erwähnt.
wc -c <"$FILENAME"ergibt die größe bei keiner anderen kruft also size=$(wc -c <"$FILENAME").
Gilles
6
Nur noch ein Punkt: Ich habe es gerade getestet und wc -c < filescheint sehr schnell zu sein, zumindest unter OS X. Ich vermute, dass wc die Köpfe hat, um zu versuchen, die Datei zu statisieren, wenn nur -c angegeben wird.
Edward Falk
4
@EdwardFalk: GNU wc -cverwendet fstat, sucht dann aber den vorletzten Block der Datei und liest die letzten bis zu st_blksizeBytes. Anscheinend liegt dies daran, dass Dateien in Linux /procund /sysz. B. nur ungefähre stat-Größen haben und wcdie tatsächliche Größe angeben möchten, nicht die stat-gemeldete Größe. Ich denke, es wäre seltsam wc -c, eine andere Größe als zu melden wc, aber es ist nicht ratsam, Daten aus der Datei zu lesen, wenn es sich um eine normale Festplattendatei handelt und sie sich nicht im Speicher befindet. Oder noch schlimmer, Near-Line-Bandspeicher ...
Peter Cordes
1
Anscheinend printfsieht die Einrückung noch aus, zB printf "Size: $size"-> size: <4 spaces> 54339. Auf der anderen Seite echoignoriert das Leerzeichen. Wie kann man es konsistent machen?
Eugene Kulabuhov
2
@keithpjolley: Durch einen Anruf fstat. Laufen strace wc -c </etc/passwdSie und Sie können sehen, was es tut.
Nemo
48
BSDs (Mac OS Xs) stathaben ein unterschiedliches Formatargument-Flag und unterschiedliche Feldspezifizierer. Von man stat(1):
-f format: Informationen im angegebenen Format anzeigen. Im Abschnitt FORMATE finden Sie eine Beschreibung der gültigen Formate.
gibt die Anzahl der Bytes an, die aus der Datei gelesen werden können. IOW, es ist die Größe des Inhalts der Datei. Der Inhalt der Datei wird jedoch gelesen (es sei denn, die Datei ist eine reguläre Datei oder ein Symlink zu einer regulären Datei, was in den meisten wcImplementierungen eine Optimierung darstellt). Das kann Nebenwirkungen haben. Zum Beispiel kann für eine Named Pipe, was gelesen wurde, nicht mehr wieder gelesen werden und für Dinge wie /dev/zerooder /dev/randomdie von unendlicher Größe, wird es eine Weile dauern. Das bedeutet auch, dass Sie eine readBerechtigung für die Datei benötigen und der Zeitstempel des letzten Zugriffs der Datei möglicherweise aktualisiert wird.
Das ist Standard und portabel. Beachten Sie jedoch, dass einige wcImplementierungen führende Leerzeichen in dieser Ausgabe enthalten können. Eine Möglichkeit, sie loszuwerden, besteht darin, Folgendes zu verwenden:
size=$(($(wc -c <"$file")))
oder um einen Fehler bezüglich eines leeren arithmetischen Ausdrucks in dashoder yashwenn wckeine Ausgabe erzeugt wird (wie wenn die Datei nicht geöffnet werden kann) zu vermeiden :
size=$(($(wc -c <"$file")+0))
ksh93has wcbuiltin (vorausgesetzt, Sie aktivieren es, Sie können es auch aufrufen als command /opt/ast/bin/wc), wodurch es für reguläre Dateien in dieser Shell am effizientesten ist.
Verschiedene Systeme haben einen Befehl stat, der als Schnittstelle zu den Systemaufrufen stat()oder bezeichnet lstat()wird.
Diese Berichtsinformationen befinden sich in der Inode. Eine dieser Informationen ist das st_sizeAttribut. Bei regulären Dateien entspricht dies der Größe des Inhalts (wie viele Daten ohne Fehler daraus gelesen werden konnten (dies wird von den meisten wc -cImplementierungen für die Optimierung verwendet)). Bei Symlinks entspricht dies der Größe des Zielpfads in Byte. Bei Named Pipes ist es je nach System entweder 0 oder die Anzahl der Bytes, die sich derzeit im Pipe-Puffer befinden. Dasselbe gilt für Blockgeräte, bei denen je nach System 0 oder die Größe des zugrunde liegenden Speichers in Byte angegeben wird.
Sie benötigen keine Leseberechtigung für die Datei, um diese Informationen abzurufen, sondern nur die Suchberechtigung für das Verzeichnis, mit dem sie verknüpft ist.
liefert das st_sizeAttribut von $file( lstat()) oder:
stat -s --"$file"
Das Gleiche gilt, außer wenn $filees sich um einen Symlink handelt. In diesem Fall handelt es sich um den st_sizeder Datei nach der Auflösung des Symlinks.
zshstateingebaut (jetzt auch bekannt als zstat) in das zsh/statModul (geladen mit zmodload zsh/stat) (1997):
stat -L +size -- $file # st_size of file
stat +size -- $file # after symlink resolution
oder in einer Variablen speichern:
stat -L -A size +size -- $file
Offensichtlich ist das die effizienteste in dieser Shell.
GNUstat (2001); statseit 2005 auch in BusyBox (kopiert von GNU stat):
stat -c %s --"$file"# st_size of file
stat -Lc%s --"$file"# after symlink resolution
(Beachten Sie, dass die Bedeutung von -Lim Vergleich zu IRIX oder umgekehrt ist zshstat.
stat -f %z --"$file"# st_size of file
stat -Lf%z --"$file"# after symlink resolution
Oder Sie können die Verwendung stat()/ lstat()Funktion einiger Skriptsprache wie perl:
perl -le 'print((lstat shift)[7])'--"$file"
AIX verfügt auch über einen istatBefehl, der alle Informationen ausgibt stat()(nicht lstat(), funktioniert also nicht bei Symlinks) und mit dem Sie nachbearbeiten können, zum Beispiel:
Lange bevor GNU seinen statBefehl einführte , konnte dasselbe mit dem GNU- findBefehl mit seinem -printfPrädikat erreicht werden (bereits 1991):
find --"$file"-prune -printf '%s\n'# st_size of file
find -L --"$file"-prune -printf '%s\n'# after symlink resolution
Ein Problem ist aber, dass nicht funktioniert , wenn $filebeginnt mit -oder ist ein findPrädikat (wie !, (...).
Der Standardbefehl zum Abrufen der stat()/ lstat()-Information lautet ls.
POSIXly können Sie tun:
LC_ALL=C ls -dn --"$file"| awk '{print $5; exit}'
und -Lfür das gleiche nach Symlink-Auflösung hinzufügen . Dies funktioniert jedoch nicht für Gerätedateien, bei denen das fünfte Feld die Hauptnummer des Geräts anstelle der Größe ist.
Bei Blockgeräten haben Systeme, für stat()die 0 zurückgegeben wird st_size, normalerweise andere APIs, um die Größe des Blockgeräts zu melden. Zum Beispiel verfügt Linux über die BLKGETSIZE64ioctl()und die meisten Linux-Distributionen werden jetzt mit einem blockdevBefehl ausgeliefert, der diese verwenden kann:
blockdev --getsize64 --"$device_file"
Dafür benötigen Sie jedoch eine Leseberechtigung für die Gerätedatei. Es ist normalerweise möglich, die Größe auf andere Weise abzuleiten. Zum Beispiel (noch unter Linux):
lsblk -bdno size --"$device_file"
Sollte funktionieren, außer für leere Geräte.
Ein Ansatz, der für alle durchsuchbaren Dateien funktioniert (einschließlich regulärer Dateien, der meisten Blockgeräte und einiger Zeichengeräte), besteht darin, die Datei zu öffnen und bis zum Ende zu suchen:
Mit zsh(nach dem Laden des zsh/systemModuls):
{sysseek -w end 0&& size=$((systell(0)))}< $file
Mit ksh93:
<"$file"<#((size=EOF))
oder
{ size=$(<#((EOF)));}<"$file"
mit perl:
perl -le 'seek STDIN, 0, 2 or die "seek: $!"; print tell STDIN'<"$file"
Für Named Pipes, haben wir gesehen , dass einige Systeme (AIX, Solaris, HP / UX zumindest) die Datenmenge in dem Rohrpuffer in zur Verfügung stellen stat()ist st_size. Einige (wie Linux oder FreeBSD) tun dies nicht.
Zumindest unter Linux können Sie das verwenden, FIONREADioctl()nachdem Sie die Pipe geöffnet haben (im Lese- und Schreibmodus, um ein Hängen zu vermeiden):
Beachten Sie jedoch, dass der Inhalt der Pipe zwar nicht gelesen wird , das bloße Öffnen der benannten Pipe jedoch dennoch Nebenwirkungen haben kann. Wir fuserüberprüfen zunächst, ob in einem Prozess bereits eine Pipe offen ist, um dies zu beheben. Dies ist jedoch nicht kinderleicht, da fusermöglicherweise nicht alle Prozesse überprüft werden können.
Bisher haben wir nur die Größe der Primärdaten in Betracht gezogen, die mit den Dateien verknüpft sind. Dies berücksichtigt nicht die Größe der Metadaten und die gesamte unterstützende Infrastruktur, die zum Speichern dieser Datei erforderlich ist.
Ein weiteres von zurückgegebenes Inode-Attribut stat()ist st_blocks. Das ist die Anzahl von 512-Byte-Blöcken, die zum Speichern der Daten der Datei verwendet werden (und manchmal auch einiger ihrer Metadaten wie der erweiterten Attribute auf ext4-Dateisystemen unter Linux). Dies schließt weder den Inode selbst noch die Einträge in den Verzeichnissen ein, mit denen die Datei verknüpft ist.
Größe und Datenträgerverwendung hängen nicht unbedingt eng zusammen, da Komprimierung, Spärlichkeit (manchmal einige Metadaten) und zusätzliche Infrastruktur wie indirekte Blöcke in einigen Dateisystemen Einfluss auf letztere haben.
Dies wird normalerweise duverwendet, um die Festplattennutzung zu melden. Mit den meisten der oben aufgeführten Befehle können Sie diese Informationen abrufen.
POSIXLY_CORRECT=1 ls -sd -- "$file" | awk '{print $1; exit}'
POSIXLY_CORRECT=1 du -s -- "$file" (Nicht für Verzeichnisse, in denen die Datenträgerverwendung der Dateien enthalten wäre).
eindeutig die umfassendste und informativste Antwort. Dankeschön. Ich kann dies verwenden, um plattformübergreifende Bash-Skripte mit den BSD- und GNU-Statistiken zu erstellen. info
oligofren
1
Unterhaltsame Tatsache: GNU coreutils wc -cverwendet fstat, liest dann aber die letzten bis zu st_blksizeBytes. Anscheinend liegt dies daran, dass Dateien in Linux /procund /sysz. B. Stat-Größen nur ungefähr sind . Dies ist gut für die Korrektheit, aber schlecht, wenn sich das Ende der Datei auf der Festplatte und nicht im Speicher befindet (insbesondere, wenn es für viele Dateien in einer Schleife verwendet wird). Und sehr schlecht, wenn die Datei auf Nearline-Bandspeicher oder z. B. ein FUSE-Dateisystem mit transparenter Dekomprimierung migriert wird.
Peter Cordes
würde diese Arbeit nicht auchls -go file | awk '{print $3}'
Steven Penny
@StevenPenny das -gowären die SysV, sie würden auf BSDs nicht funktionieren (optional (XSI) in POSIX). Sie müssten auch ls -god file | awk '{print $3; exit}'( -ddamit es auf Verzeichnissen funktioniert, exitfür Symlinks mit Zeilenumbrüchen im Ziel). Die Probleme mit Gerätedateien bleiben ebenfalls bestehen.
Stéphane Chazelas
1
@ αғsнιη Die Unix-API unterscheidet nicht zwischen Text- und Binärdateien. Es sind alles Sequenzen von Bytes. Einige Anwendungen möchten diese Bytes möglicherweise als Text interpretieren, aber offensichtlich nicht wc -cdie Anzahl der Bytes.
Stéphane Chazelas
22
Dieses Skript kombiniert viele Möglichkeiten, um die Dateigröße zu berechnen:
(
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}'
Das Skript funktioniert auf vielen Unix-Systemen, einschließlich Linux, BSD, OSX, Solaris, SunOS usw.
Die Dateigröße gibt die Anzahl der Bytes an. Dies ist die scheinbare Größe, dh die Bytes, die die Datei auf einem typischen Datenträger ohne besondere Komprimierung, ohne besondere Bereiche mit geringer Dichte oder ohne zugewiesene Blöcke usw. verwendet.
Ich denke, beide ls -lund statBefehl geben zuverlässige Größeninformationen. Ich habe keinen Hinweis auf das Gegenteil gefunden. ls -sgibt die Größe in Anzahl von Blöcken an.
dabest1
2
@ dabest1 Es ist in gewisser Hinsicht nicht zuverlässig, dass die Ausgabe in einem anderen Unix unterschiedlich sein kann (und in einigen Unixen auch).
Eugene Bujak
Ja, IIRC, Solaris hat den Gruppennamen standardmäßig nicht angezeigt, was zu weniger Spalten in der Ausgabe führte.
Edward Falk
Da die Größe rein numerisch ist, umgeben von Leerzeichen, und das Datumsjahr in einem definierten Format rein numerisch ist, kann mit einem regulären Ausdruck Benutzer + Besitzer als ein Feld behandelt werden, unabhängig davon, ob die Gruppe vorhanden war oder nicht. (eine Übung für den Leser!)
MikeW
5
du filename Zeigt die Festplattennutzung in Bytes an.
Ich bevorzuge du -h filename, was dir die Größe in einem für Menschen lesbaren Format gibt.
Diese Variante dudruckt die Größe in Blöcken von 1024 Bytes aus, keine einfache Anzahl von Bytes.
Peter Lyons
Beachten Sie, dass Standard dueine Ausgabe in 512-Byte-Einheiten liefert. GNU duverwendet stattdessen Kibibytes, sofern dies nicht POSIXLY_CORRECTin seiner Umgebung mit aufgerufen wird .
Stéphane Chazelas
1
Bei Dateien vom Typ Verzeichnis gibt dies die Plattenbelegung des Verzeichnisses, aber auch aller anderen darin enthaltenen Dateien (rekursiv) an.
Stéphane Chazelas
3
Erstellen Sie in Ihren Shell-Skripten kleine Dienstprogrammfunktionen, an die Sie delegieren können.
Beispiel
#! /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
Gestützt auf Informationen aus der Antwort von @ Stéphane Chazelas.
Siehe auch gzip -v < file > /dev/null, um die Komprimierbarkeit einer Datei zu überprüfen.
Stéphane Chazelas
@ StéphaneChazelas nicht sicher, ob ich denke, dass es eine Verbesserung war. Diese case-Anweisungen können noobs leicht abschrecken. Ich kann mich bestimmt nie erinnern, wie ich sie richtig hinbekomme :-) Sind case-Anweisungen von Natur aus portabler, seitdem Sie es getan haben? Ich sehe den Punkt, wenn es mehr als zwei Fälle gibt, aber sonst ... +
Oligofren
1
Ich nehme an, es ist auch Geschmackssache, aber hier ist es der typische Fall, in dem Sie eine caseAussage verwenden möchten . caseist das Bourne / POSIX-Konstrukt für den Mustervergleich. [[...]]ist nur ksh / bash / zsh (mit Variationen).
Stéphane Chazelas
2
Ich habe einen AWK 1 Liner gefunden und er hatte einen Fehler, aber ich habe ihn behoben. Ich habe auch in PetaBytes nach TeraBytes hinzugefügt.
Da stat nicht auf jedem einzelnen System vorhanden ist, können Sie die AWK-Lösung fast immer verwenden. Beispiel; Der Raspberry Pi hat keinen Status , aber einen awk .
Völlig NICHT das, was der OP verlangte, sondern nette kleine Arbeit.
Gypsy Spellweaver
0
Eine andere POSIX-konforme Methode wäre die Verwendung awkder length()Funktion, die die Länge in Zeichen in jeder Zeile der Eingabedatei ohne die Zeilenumbrüche zurückgibt. Also indem du tust
awk '{ sum+=length } END { print sum+NR }' file
Wir stellen sicher, dass NRhinzugefügt wird sum, wodurch sich die Gesamtzahl der Zeichen und die Gesamtzahl der in der Datei gefundenen Zeilenumbrüche ergibt. Die length()Funktion in awknimmt ein Argument an, das standardmäßig length($0)für die aktuelle ganze Zeile steht.
Nicht, wenn die letzte Zeile nicht in einer neuen Zeile endet: printf 'a\nb' | awk '{ sum+=length } END { print sum+NR }'sollte 3, aber 4 ausgeben.
Isaac vor
-1
Ich mag die WC-Option selbst. Gepaart mit 'bc' können Sie Dezimalstellen an beliebig vielen Stellen eingeben.
Ich wollte ein Skript verbessern, das die Spalte "Dateigröße" eines "ls -alh" -Befehls enthielt. Ich wollte nicht nur ganzzahlige Dateigrößen, und zwei Dezimalstellen schienen zu passen. Nachdem ich diese Diskussion gelesen hatte, kam ich auf den folgenden Code.
Ich schlage vor, die Linie an den Semikolons zu brechen, wenn Sie dies in ein Skript aufnehmen.
Mein Skript heißt gpfl , für "Bilddateilänge abrufen ". Ich benutze es nach dem Mogrifizieren einer Datei in imagemagick, bevor ich ein Bild in einem GUI-JPEG-Viewer öffne oder neu lade.
Ich weiß nicht, wie dies als "Antwort" bewertet wird, da es viel von dem leiht, was bereits angeboten und diskutiert wurde. Also lasse ich es dort.
Ich würde lieber "stat" oder "ls" verwenden. Normalerweise verwende ich "wc" nicht zum Abrufen der Dateigröße, da es die gesamte Datei physisch liest. Wenn Sie viele oder besonders große Dateien haben, kann dies viel Zeit in Anspruch nehmen. Aber Ihre Lösung ist kreativ ... + 1.
Kevin Fegan
2
Ich stimme dem Gedanken zu, "stat" anstelle von "wc" für die Dateigröße zu verwenden. Wenn Sie jedoch "wc -c" verwenden, werden keine Daten gelesen. Stattdessen wird mit lseek die Anzahl der Bytes in einer Datei ermittelt. lingrok.org/xref/coreutils/src/wc.c#228
bbaja42
1
@ bbaja42: beachte, dass GNU Coreutils wcden letzten Block der Datei liest, falls dies stat.st_sizenur eine Annäherung war (wie für Linux /procund /sysDateien). Ich vermute, sie haben beschlossen, den Hauptkommentar nicht komplizierter zu gestalten, als sie diese Logik ein paar Zeilen später hinzufügten
Stimmen Sie dann eine oder mehrere der vorhandenen Antworten hoch, in denen stat erwähnt wird. Keine Notwendigkeit, es noch einmal zu wiederholen ...
Jeff Schaller
1
@ JeffSchaller Ich habe gerade Stephanes Antwort auf Ihre Anweisungen positiv bewertet. Ich denke, es ist zu kompliziert für meine Zwecke. Deshalb habe ich diese einfache Antwort für Gleichgesinnte veröffentlicht.
WinEunuuchs2Unix
1
Danke; Es ist nur so, dass eine sechste Instanz einer "stat" -Antwort diese Fragen und Antworten nicht vereinfacht, sondern einen neuen Leser dazu bringt, sich die Frage zu stellen, inwiefern sich diese Antwort von den anderen unterscheidet. und führen zu mehr Verwirrung statt weniger.
Jeff Schaller
@ JeffSchaller, denke ich. Aber ich könnte mich über die vielen duund wcAntworten beschweren , die einen Haftungsausschluss haben sollten. TUN SIE DAS NIE im wirklichen Leben. Ich habe meine Antwort heute Abend in einer realen Anwendung verwendet und fand, dass es sich lohnt, sie zu teilen. Ich denke, wir haben alle unsere Meinung zuckt mit den Schultern .
pv
undcat
für einen Kopierbefehl, der den Fortschritt und die ETA anzeigt :)Antworten:
Ihre beste Wahl, wenn Sie auf einem GNU-System arbeiten:
Von mann stat :
In einem Bash-Skript:
HINWEIS: Informationen zur Verwendung von stat im Terminal unter Mac OS X finden Sie in der Antwort von @ chbrown.
quelle
stat
ist der einfachste Weg, vorausgesetzt, Sie verwenden Linux oder Cygwin (stat
nicht Standard).wc -c
wie von Eugéne vorgeschlagen, ist portabel.stat: illegal option -- c
stat --printf="%s" file.txt
gibt nichts auf Debian Jessie aus ...stat -f%z myfile.tar
man stat
sagt, dass --printf die nachfolgende Newline weglässt. Verwenden Sie--format
oder-c
, um die Ausgabe anzuzeigen. Gewinnen Sie mehr Einsicht im Vergleichstat --printf="%s" file.any | xxd -
zustat -c "%s" file.any | xxd -
Das Problem bei der Verwendung
stat
ist, dass es sich um eine GNU (Linux) -Erweiterung handelt.du -k
undcut -f1
werden von POSIX spezifiziert und sind daher auf jedes Unix-System portierbar.Solaris wird zum Beispiel mit bash ausgeliefert, aber nicht mit
stat
. Das ist also nicht ganz hypothetisch.ls
Ein ähnliches Problem besteht darin, dass das genaue Format der Ausgabe nicht angegeben ist, sodass das Parsen der Ausgabe nicht portabel durchgeführt werden kann.du -h
ist auch eine GNU-Erweiterung.Wenn möglich, halten Sie sich an tragbare Konstrukte und Sie werden das Leben von jemandem in Zukunft einfacher machen. Vielleicht deine eigene.
quelle
du
gibt nicht die Größe der Datei an, sondern gibt einen Hinweis darauf, wie viel Speicherplatz die Datei belegt, was sich geringfügig unterscheidet (normalerweisedu
ist die angegebene Größe die Größe der Datei, aufgerundet auf die nächste Anzahl von Blöcken, bei denen ein Block vorhanden ist beträgt typischerweise 512B oder 1kB oder 4kB).--bytes
oder-b
anstelle von-k
die akzeptierte Antwort sein.-h
Option ("Mensch") vondu
liefert die am besten geeignete Antwort für allgemeine Fällefile_size=`du -h "$filename" | cut -f1
:, da K (Kilobyte), M (Megabyte) oder G (Gigabyte) angezeigt werden.-h
eine GNU-Erweiterung; Es ist nicht StandardSie können auch den Befehl "word count" (
wc
) verwenden:Das Problem dabei
wc
ist, dass der Dateiname hinzugefügt und die Ausgabe eingerückt wird. Zum Beispiel:Wenn Sie vermeiden möchten, einen vollständig interpretierten Sprach- oder Stream-Editor zu verketten, um die Dateigröße zu ermitteln, leiten Sie einfach die Eingabe aus der Datei um, sodass
wc
der Dateiname nicht angezeigt wird:Diese letzte Form kann mit der Befehlsersetzung verwendet werden, um den gesuchten Wert als Shell-Variable zu erfassen, wie von Gilles unten erwähnt.
quelle
wc -c <"$FILENAME"
ergibt die größe bei keiner anderen kruft alsosize=$(wc -c <"$FILENAME")
.wc -c < file
scheint sehr schnell zu sein, zumindest unter OS X. Ich vermute, dass wc die Köpfe hat, um zu versuchen, die Datei zu statisieren, wenn nur -c angegeben wird.wc -c
verwendetfstat
, sucht dann aber den vorletzten Block der Datei und liest die letzten bis zust_blksize
Bytes. Anscheinend liegt dies daran, dass Dateien in Linux/proc
und/sys
z. B. nur ungefähre stat-Größen haben undwc
die tatsächliche Größe angeben möchten, nicht die stat-gemeldete Größe. Ich denke, es wäre seltsamwc -c
, eine andere Größe als zu meldenwc
, aber es ist nicht ratsam, Daten aus der Datei zu lesen, wenn es sich um eine normale Festplattendatei handelt und sie sich nicht im Speicher befindet. Oder noch schlimmer, Near-Line-Bandspeicher ...printf
sieht die Einrückung noch aus, zBprintf "Size: $size"
->size: <4 spaces> 54339
. Auf der anderen Seiteecho
ignoriert das Leerzeichen. Wie kann man es konsistent machen?fstat
. Laufenstrace wc -c </etc/passwd
Sie und Sie können sehen, was es tut.BSDs (Mac OS Xs)
stat
haben ein unterschiedliches Formatargument-Flag und unterschiedliche Feldspezifizierer. Vonman stat(1)
:-f format
: Informationen im angegebenen Format anzeigen. Im Abschnitt FORMATE finden Sie eine Beschreibung der gültigen Formate.z
: Die Größe der Datei in Bytes.Also alles zusammen jetzt:
quelle
Kommt darauf an, was du mit Größe meinst .
gibt die Anzahl der Bytes an, die aus der Datei gelesen werden können. IOW, es ist die Größe des Inhalts der Datei. Der Inhalt der Datei wird jedoch gelesen (es sei denn, die Datei ist eine reguläre Datei oder ein Symlink zu einer regulären Datei, was in den meisten
wc
Implementierungen eine Optimierung darstellt). Das kann Nebenwirkungen haben. Zum Beispiel kann für eine Named Pipe, was gelesen wurde, nicht mehr wieder gelesen werden und für Dinge wie/dev/zero
oder/dev/random
die von unendlicher Größe, wird es eine Weile dauern. Das bedeutet auch, dass Sie eineread
Berechtigung für die Datei benötigen und der Zeitstempel des letzten Zugriffs der Datei möglicherweise aktualisiert wird.Das ist Standard und portabel. Beachten Sie jedoch, dass einige
wc
Implementierungen führende Leerzeichen in dieser Ausgabe enthalten können. Eine Möglichkeit, sie loszuwerden, besteht darin, Folgendes zu verwenden:oder um einen Fehler bezüglich eines leeren arithmetischen Ausdrucks in
dash
oderyash
wennwc
keine Ausgabe erzeugt wird (wie wenn die Datei nicht geöffnet werden kann) zu vermeiden :ksh93
haswc
builtin (vorausgesetzt, Sie aktivieren es, Sie können es auch aufrufen alscommand /opt/ast/bin/wc
), wodurch es für reguläre Dateien in dieser Shell am effizientesten ist.Verschiedene Systeme haben einen Befehl
stat
, der als Schnittstelle zu den Systemaufrufenstat()
oder bezeichnetlstat()
wird.Diese Berichtsinformationen befinden sich in der Inode. Eine dieser Informationen ist das
st_size
Attribut. Bei regulären Dateien entspricht dies der Größe des Inhalts (wie viele Daten ohne Fehler daraus gelesen werden konnten (dies wird von den meistenwc -c
Implementierungen für die Optimierung verwendet)). Bei Symlinks entspricht dies der Größe des Zielpfads in Byte. Bei Named Pipes ist es je nach System entweder 0 oder die Anzahl der Bytes, die sich derzeit im Pipe-Puffer befinden. Dasselbe gilt für Blockgeräte, bei denen je nach System 0 oder die Größe des zugrunde liegenden Speichers in Byte angegeben wird.Sie benötigen keine Leseberechtigung für die Datei, um diese Informationen abzurufen, sondern nur die Suchberechtigung für das Verzeichnis, mit dem sie verknüpft ist.
In chronologischer Reihenfolge gibt es:
IRIX
stat
(90er Jahre):liefert das
st_size
Attribut von$file
(lstat()
) oder:Das Gleiche gilt, außer wenn
$file
es sich um einen Symlink handelt. In diesem Fall handelt es sich um denst_size
der Datei nach der Auflösung des Symlinks.zsh
stat
eingebaut (jetzt auch bekannt alszstat
) in daszsh/stat
Modul (geladen mitzmodload zsh/stat
) (1997):oder in einer Variablen speichern:
Offensichtlich ist das die effizienteste in dieser Shell.
GNU
stat
(2001);stat
seit 2005 auch in BusyBox (kopiert von GNUstat
):(Beachten Sie, dass die Bedeutung von
-L
im Vergleich zu IRIX oder umgekehrt istzsh
stat
.BSDs
stat
(2002):Oder Sie können die Verwendung
stat()
/lstat()
Funktion einiger Skriptsprache wieperl
:AIX verfügt auch über einen
istat
Befehl, der alle Informationen ausgibtstat()
(nichtlstat()
, funktioniert also nicht bei Symlinks) und mit dem Sie nachbearbeiten können, zum Beispiel:(danke @JeffSchaller für die Hilfe beim Herausfinden der Details ).
In
tcsh
:(Größe nach Symlinkauflösung)
Lange bevor GNU seinen
stat
Befehl einführte , konnte dasselbe mit dem GNU-find
Befehl mit seinem-printf
Prädikat erreicht werden (bereits 1991):Ein Problem ist aber, dass nicht funktioniert , wenn
$file
beginnt mit-
oder ist einfind
Prädikat (wie!
,(
...).Der Standardbefehl zum Abrufen der
stat()
/lstat()
-Information lautetls
.POSIXly können Sie tun:
und
-L
für das gleiche nach Symlink-Auflösung hinzufügen . Dies funktioniert jedoch nicht für Gerätedateien, bei denen das fünfte Feld die Hauptnummer des Geräts anstelle der Größe ist.Bei Blockgeräten haben Systeme, für
stat()
die 0 zurückgegeben wirdst_size
, normalerweise andere APIs, um die Größe des Blockgeräts zu melden. Zum Beispiel verfügt Linux über dieBLKGETSIZE64
ioctl()
und die meisten Linux-Distributionen werden jetzt mit einemblockdev
Befehl ausgeliefert, der diese verwenden kann:Dafür benötigen Sie jedoch eine Leseberechtigung für die Gerätedatei. Es ist normalerweise möglich, die Größe auf andere Weise abzuleiten. Zum Beispiel (noch unter Linux):
Sollte funktionieren, außer für leere Geräte.
Ein Ansatz, der für alle durchsuchbaren Dateien funktioniert (einschließlich regulärer Dateien, der meisten Blockgeräte und einiger Zeichengeräte), besteht darin, die Datei zu öffnen und bis zum Ende zu suchen:
Mit
zsh
(nach dem Laden deszsh/system
Moduls):Mit
ksh93
:oder
mit
perl
:Für Named Pipes, haben wir gesehen , dass einige Systeme (AIX, Solaris, HP / UX zumindest) die Datenmenge in dem Rohrpuffer in zur Verfügung stellen
stat()
istst_size
. Einige (wie Linux oder FreeBSD) tun dies nicht.Zumindest unter Linux können Sie das verwenden,
FIONREAD
ioctl()
nachdem Sie die Pipe geöffnet haben (im Lese- und Schreibmodus, um ein Hängen zu vermeiden):Beachten Sie jedoch, dass der Inhalt der Pipe zwar nicht gelesen wird , das bloße Öffnen der benannten Pipe jedoch dennoch Nebenwirkungen haben kann. Wir
fuser
überprüfen zunächst, ob in einem Prozess bereits eine Pipe offen ist, um dies zu beheben. Dies ist jedoch nicht kinderleicht, dafuser
möglicherweise nicht alle Prozesse überprüft werden können.Bisher haben wir nur die Größe der Primärdaten in Betracht gezogen, die mit den Dateien verknüpft sind. Dies berücksichtigt nicht die Größe der Metadaten und die gesamte unterstützende Infrastruktur, die zum Speichern dieser Datei erforderlich ist.
Ein weiteres von zurückgegebenes Inode-Attribut
stat()
istst_blocks
. Das ist die Anzahl von 512-Byte-Blöcken, die zum Speichern der Daten der Datei verwendet werden (und manchmal auch einiger ihrer Metadaten wie der erweiterten Attribute auf ext4-Dateisystemen unter Linux). Dies schließt weder den Inode selbst noch die Einträge in den Verzeichnissen ein, mit denen die Datei verknüpft ist.Größe und Datenträgerverwendung hängen nicht unbedingt eng zusammen, da Komprimierung, Spärlichkeit (manchmal einige Metadaten) und zusätzliche Infrastruktur wie indirekte Blöcke in einigen Dateisystemen Einfluss auf letztere haben.
Dies wird normalerweise
du
verwendet, um die Festplattennutzung zu melden. Mit den meisten der oben aufgeführten Befehle können Sie diese Informationen abrufen.POSIXLY_CORRECT=1 ls -sd -- "$file" | awk '{print $1; exit}'
POSIXLY_CORRECT=1 du -s -- "$file"
(Nicht für Verzeichnisse, in denen die Datenträgerverwendung der Dateien enthalten wäre).find -- "$file" -printf '%b\n'
zstat -L +block -- $file
stat -c %b -- "$file"
stat -f %b -- "$file"
perl -le 'print((lstat shift)[12])' -- "$file"
quelle
wc -c
verwendetfstat
, liest dann aber die letzten bis zust_blksize
Bytes. Anscheinend liegt dies daran, dass Dateien in Linux/proc
und/sys
z. B. Stat-Größen nur ungefähr sind . Dies ist gut für die Korrektheit, aber schlecht, wenn sich das Ende der Datei auf der Festplatte und nicht im Speicher befindet (insbesondere, wenn es für viele Dateien in einer Schleife verwendet wird). Und sehr schlecht, wenn die Datei auf Nearline-Bandspeicher oder z. B. ein FUSE-Dateisystem mit transparenter Dekomprimierung migriert wird.ls -go file | awk '{print $3}'
-go
wären die SysV, sie würden auf BSDs nicht funktionieren (optional (XSI) in POSIX). Sie müssten auchls -god file | awk '{print $3; exit}'
(-d
damit es auf Verzeichnissen funktioniert,exit
für Symlinks mit Zeilenumbrüchen im Ziel). Die Probleme mit Gerätedateien bleiben ebenfalls bestehen.wc -c
die Anzahl der Bytes.Dieses Skript kombiniert viele Möglichkeiten, um die Dateigröße zu berechnen:
Das Skript funktioniert auf vielen Unix-Systemen, einschließlich Linux, BSD, OSX, Solaris, SunOS usw.
Die Dateigröße gibt die Anzahl der Bytes an. Dies ist die scheinbare Größe, dh die Bytes, die die Datei auf einem typischen Datenträger ohne besondere Komprimierung, ohne besondere Bereiche mit geringer Dichte oder ohne zugewiesene Blöcke usw. verwendet.
Dieses Skript enthält eine Produktionsversion mit mehr Hilfe und mehr Optionen: https://github.com/SixArm/file-size
quelle
stat scheint dies mit den wenigsten Systemaufrufen zu tun:
quelle
ls -l filename
gibt Ihnen viele Informationen über eine Datei, einschließlich Dateigröße, Berechtigungen und Eigentümer.Die Dateigröße in der fünften Spalte und wird in Bytes angezeigt. Im folgenden Beispiel beträgt die Dateigröße knapp 2 KB:
Bearbeiten: Dies ist anscheinend nicht so zuverlässig wie der
stat
Befehl.quelle
ls -l
undstat
Befehl geben zuverlässige Größeninformationen. Ich habe keinen Hinweis auf das Gegenteil gefunden.ls -s
gibt die Größe in Anzahl von Blöcken an.du filename
Zeigt die Festplattennutzung in Bytes an.Ich bevorzuge
du -h filename
, was dir die Größe in einem für Menschen lesbaren Format gibt.quelle
stat -c "%s"
;)du
druckt die Größe in Blöcken von 1024 Bytes aus, keine einfache Anzahl von Bytes.du
eine Ausgabe in 512-Byte-Einheiten liefert. GNUdu
verwendet stattdessen Kibibytes, sofern dies nichtPOSIXLY_CORRECT
in seiner Umgebung mit aufgerufen wird .Erstellen Sie in Ihren Shell-Skripten kleine Dienstprogrammfunktionen, an die Sie delegieren können.
Beispiel
Gestützt auf Informationen aus der Antwort von @ Stéphane Chazelas.
quelle
gzip -v < file > /dev/null
, um die Komprimierbarkeit einer Datei zu überprüfen.case
Aussage verwenden möchten .case
ist das Bourne / POSIX-Konstrukt für den Mustervergleich.[[...]]
ist nur ksh / bash / zsh (mit Variationen).Ich habe einen AWK 1 Liner gefunden und er hatte einen Fehler, aber ich habe ihn behoben. Ich habe auch in PetaBytes nach TeraBytes hinzugefügt.
Da stat nicht auf jedem einzelnen System vorhanden ist, können Sie die AWK-Lösung fast immer verwenden. Beispiel; Der Raspberry Pi hat keinen Status , aber einen awk .
quelle
Eine andere POSIX-konforme Methode wäre die Verwendung
awk
derlength()
Funktion, die die Länge in Zeichen in jeder Zeile der Eingabedatei ohne die Zeilenumbrüche zurückgibt. Also indem du tustWir stellen sicher, dass
NR
hinzugefügt wirdsum
, wodurch sich die Gesamtzahl der Zeichen und die Gesamtzahl der in der Datei gefundenen Zeilenumbrüche ergibt. Dielength()
Funktion inawk
nimmt ein Argument an, das standardmäßiglength($0)
für die aktuelle ganze Zeile steht.quelle
printf 'a\nb' | awk '{ sum+=length } END { print sum+NR }'
sollte 3, aber 4 ausgeben.Ich mag die WC-Option selbst. Gepaart mit 'bc' können Sie Dezimalstellen an beliebig vielen Stellen eingeben.
Ich wollte ein Skript verbessern, das die Spalte "Dateigröße" eines "ls -alh" -Befehls enthielt. Ich wollte nicht nur ganzzahlige Dateigrößen, und zwei Dezimalstellen schienen zu passen. Nachdem ich diese Diskussion gelesen hatte, kam ich auf den folgenden Code.
Ich schlage vor, die Linie an den Semikolons zu brechen, wenn Sie dies in ein Skript aufnehmen.
file=$1; string=$(wc -c $file); bite=${string% *}; okay=$(echo "scale=2; $bite/1024" | bc);friend=$(echo -e "$file $okay" "kb"); echo -e "$friend"
Mein Skript heißt gpfl , für "Bilddateilänge abrufen ". Ich benutze es nach dem Mogrifizieren einer Datei in imagemagick, bevor ich ein Bild in einem GUI-JPEG-Viewer öffne oder neu lade.
Ich weiß nicht, wie dies als "Antwort" bewertet wird, da es viel von dem leiht, was bereits angeboten und diskutiert wurde. Also lasse ich es dort.
BZT
quelle
wc
den letzten Block der Datei liest, falls diesstat.st_size
nur eine Annäherung war (wie für Linux/proc
und/sys
Dateien). Ich vermute, sie haben beschlossen, den Hauptkommentar nicht komplizierter zu gestalten, als sie diese Logik ein paar Zeilen später hinzufügtenDie schnellste und einfachste Methode (IMO) ist:
quelle
du
undwc
Antworten beschweren , die einen Haftungsausschluss haben sollten. TUN SIE DAS NIE im wirklichen Leben. Ich habe meine Antwort heute Abend in einer realen Anwendung verwendet und fand, dass es sich lohnt, sie zu teilen. Ich denke, wir haben alle unsere Meinung zuckt mit den Schultern .