Unter Linux verwende ich stat --format="%s" FILE
, aber Solaris, auf das ich Zugriff habe, hat keinen stat-Befehl. Was soll ich dann verwenden?
Ich schreibe Bash-Skripte und kann keine neue Software auf dem System installieren.
Ich habe darüber nachgedacht, bereits zu verwenden:
perl -e '@x=stat(shift);print $x[7]' FILE
oder auch:
ls -nl FILE | awk '{print $5}'
Aber keines davon sieht sinnvoll aus - Perl ausführen, nur um die Dateigröße zu ermitteln? Oder 2 Befehle ausführen, um dasselbe zu tun?
Antworten:
wc -c < filename
(Abkürzung für Word Count,-c
druckt die Byteanzahl) ist eine tragbare POSIX- Lösung. Nur das Ausgabeformat ist möglicherweise nicht plattformübergreifend einheitlich, da möglicherweise einige Leerzeichen vorangestellt werden (was bei Solaris der Fall ist).Lassen Sie die Eingabeumleitung nicht aus. Wenn die Datei als Argument übergeben wird, wird der Dateiname nach der Anzahl der Bytes gedruckt.
Ich hatte Angst, dass es für Binärdateien nicht funktionieren würde, aber es funktioniert sowohl unter Linux als auch unter Solaris einwandfrei. Sie können es mit versuchen
wc -c < /usr/bin/wc
. Darüber hinaus wird garantiert , dass POSIX-Dienstprogramme Binärdateien verarbeiten , sofern nicht ausdrücklich anders angegeben.quelle
wc -c < file
wenn der Dateiname nicht angezeigt werden soll.wc
in einer Pipelineread()
der gesamte Stream die Bytes zählen. Diels
/awk
Lösungen (und ähnliche) einen Systemaufruf verwenden , um die Größe zu erhalten, die sollte lineare Zeit ( im Vergleich zu O (Größe))wc
mich, dass ich das letzte Mal auf einer vollen Festplatte sehr langsam war. Es war langsam genug, dass ich das Drehbuch neu schreiben konnte, bevor das erste fertig war. Ich kam hierher, um mich daran zu erinnern, wie ich es gemacht habe, lol.wc -c
; es sieht viel ordentlicher aus, aberls
+awk
ist besser für Geschwindigkeit / Ressourcennutzung. Außerdem wollte ich nur darauf hinweisen, dass Sie die Ergebnisse von tatsächlich nachbearbeiten müssen,wc
da auf einigen Systemen vor dem Ergebnis Leerzeichen stehen, die Sie möglicherweise entfernen müssen, bevor Sie Vergleiche durchführen können.wc -c
ist großartig, aber es funktioniert nicht, wenn Sie keinen Lesezugriff auf die Datei haben.Am Ende habe ich mein eigenes Programm geschrieben (wirklich klein), um nur die Größe anzuzeigen. Weitere Informationen finden Sie hier: http://fwhacking.blogspot.com/2011/03/bfsize-print-file-size-in-bytes-and.html
Die zwei saubersten Möglichkeiten meiner Meinung nach mit gängigen Linux-Tools sind:
Aber ich möchte einfach keine Parameter eingeben oder die Ausgabe weiterleiten, nur um eine Dateigröße zu erhalten, also verwende ich meine eigene bfsize.
quelle
stat
ist eine Option für sie.wc -c
4090 ms für eine 10-MB-Datei im Vergleich zu "0" ms benötigt werden. Daherstat -c %s
stimme ich zu, dass es hilfreich ist, alternative Lösungen zu haben, auch wenn sie nicht genau die gestellte Frage beantworten.stat -c %s /usr/bin/stat
stat: illegal option -- c
usage: stat [-FlLnqrsx] [-f format] [-t timefmt] [file ...]
Obwohl
du
normalerweise die Festplattennutzung und nicht die tatsächliche Datengrößedu
gedruckt wird , können GNU-Coreutils die "scheinbare Größe" der Datei in Bytes drucken:Aber es funktioniert nicht unter BSD, Solaris, macOS, ...
quelle
brew install coreutils
undgdu -b
wird den gleichen Effekt erzielenwc
das Lesen der gesamten Datei, bevor ein Ergebnis erzieltdu
wird, sofort erfolgt.du -b
in einem völlig anderen Kontext in derdu
Begründung .lstat
Aufruf verwendet, sodass die Leistung nicht von der Dateigröße abhängt. Kürzer alsstat -c '%s'
, aber weniger intuitiv und funktioniert anders für Ordner (druckt die Größe jeder darin enthaltenen Datei).du
kann mit verwendet werdendu -A -B1
, druckt das Ergebnis jedoch in Vielfachen von 1024B-Blöcken. Hat es nicht geschafft, die Anzahl der Bytes zu drucken. Auch das EinstellenBLOCKSIZE=1
in der Umgebung hilft nicht, da dann 512B-Blöcke verwendet werden.Schließlich entschied ich mich für ls und Bash-Array-Erweiterung:
Es ist nicht wirklich schön, aber zumindest macht es nur 1 Fork + Execve und es basiert nicht auf einer sekundären Programmiersprache (Perl / Ruby / Python / was auch immer).
quelle
ls -ln FILE | { read _ _ _ _ size _ && echo "$size"; }
für den zweiten Schritt der Pipeline keine Verzweigung benötigt, da es nur integrierte Funktionen verwendet, sondern Bash 4.2.37 unter Linux-Gabeln zweimal (allerdings immer noch nur eineexecve
).read _ _ _ _ size _ <<<"$(exec ls -ln /usr/bin/wc)" && echo "$size"
funktioniert mit Single Fork und Single Exec, verwendet jedoch eine temporäre Datei für die Here-Zeichenfolge. Es kann portabel gemacht werden, indem der Here-String durch ein POSX-kompatibles Here-Dokument ersetzt wird . Übrigens beachten Sie dieexec
in der Unterschale. Ohne das führt Bash eine Abzweigung für die Unterschale und eine andere für den darin ausgeführten Befehl aus. Dies ist in dem Code der Fall, den Sie in dieser Antwort angeben. auch.-l
ist in Gegenwart von überflüssig-n
. Zitiert von POSIXls
manpage :-n
: Schalten Sie den-l
(ell) Option, aber wenn die Akte der Eigentümer oder die Gruppe zu schreiben, schreiben die numerische UID oder GID der Datei statt der Benutzer- oder Gruppennamen, respectively. Deaktivieren Sie die-C
,-m
und-x
Optionen.Plattformübergreifend schnellste Lösung (verwendet nur single fork () für ls , versucht nicht, tatsächliche Zeichen zu zählen, erzeugt keine nicht benötigten awk, perl usw.).
Unter MacOS, Linux getestet - erfordert möglicherweise geringfügige Änderungen für Solaris:
Vereinfachen Sie bei Bedarf die Argumente von ls und passen Sie den Offset in $ {__ ln [3]} an.
Hinweis: folgt Symlinks.
quelle
BSDs haben
stat
mit anderen Optionen als die GNU-Coreutils eine, aber ähnliche Fähigkeiten.Dies funktioniert unter macOS (getestet am 10.12.), FreeBSD , NetBSD und OpenBSD .
quelle
stat
Nutzen.Bei der Verarbeitung der
ls -n
Ausgabe können Sie als Alternative zu schlecht portierbaren Shell-Arrays die Positionsargumente verwenden, die das einzige Array bilden und die einzigen lokalen Variablen in der Standard-Shell sind. Schließen Sie das Überschreiben von Positionsargumenten in eine Funktion ein, um die ursprünglichen Argumente für Ihr Skript oder Ihre Funktion beizubehalten.Dies teilt die Ausgabe
ln -dn
gemäß den aktuellenIFS
Einstellungen der Umgebungsvariablen auf, weist sie Positionsargumenten zu und gibt die fünfte wieder. Die-d
sicher Verzeichnisse werden richtig gehandhabt und die-n
gewährleistet , dass die Benutzer- und Gruppennamen aufgelöst nicht brauchen werden, im Gegensatz zu-l
. Außerdem könnten Benutzer- und Gruppennamen, die Leerzeichen enthalten, theoretisch die erwartete Linienstruktur durchbrechen. Sie sind normalerweise nicht erlaubt, aber diese Möglichkeit lässt den Programmierer immer noch innehalten und nachdenken.quelle
Wenn Sie
find
von GNU fileutils verwenden:Leider unterstützen andere Implementierungen von
find
normalerweise nicht-maxdepth
, noch-printf
. Dies ist beispielsweise bei Solaris und macOS der Fallfind
.quelle
size=$(test -f filename && find filename -printf '%s')
.-maxdepth
soll verhindern, dassfind
es rekursiv ist (da das,stat
was das OP ersetzen muss, nicht ist). Ihrfind
Befehl fehlt a-name
und dertest
Befehl ist nicht erforderlich.find
durchsucht seine Parameter rekursiv nach Dateien, die bestimmten Kriterien entsprechen. Wenn die Parameter keine Verzeichnisse sind, ist die Rekursion… recht einfach. Daher teste ich zuerst, dassfilename
es sich wirklich um eine vorhandene gewöhnliche Datei handelt, undfind
drucke dann ihre Größe aus, indem ich sie nirgends wiederverwenden kann.find . -maxdepth 1 -type f -name filename -printf '%s'
funktioniert nur, wenn sich die Datei im aktuellen Verzeichnis befindet und möglicherweise weiterhin jede Datei im Verzeichnis überprüft wird, was möglicherweise langsam ist. Besser nutzen (noch kürzer!)find filename -maxdepth 1 -type f -printf '%s'
.Sie können den
find
Befehl verwenden, um eine Reihe von Dateien abzurufen (hier werden temporäre Dateien extrahiert). Anschließend können Sie mit demdu
Befehl die Dateigröße jeder Datei mithilfe von-h
switch in lesbarer Form abrufen.AUSGABE:
quelle
Ihr erstes Perl-Beispiel erscheint mir nicht unangemessen.
Aus solchen Gründen bin ich vom Schreiben von Shell-Skripten (in Bash / Sh usw.) zum Schreiben aller außer den trivialsten Skripten in Perl übergegangen. Ich stellte fest, dass ich Perl für bestimmte Anforderungen starten musste, und als ich dies immer mehr tat, stellte ich fest, dass das Schreiben der Skripte in Perl wahrscheinlich leistungsfähiger war (in Bezug auf die Sprache und die große Auswahl an Bibliotheken, die über CPAN verfügbar sind) ) und effizienter, um das zu erreichen, was ich wollte.
Beachten Sie, dass andere Shell-Skriptsprachen (z. B. Python / Ruby) zweifellos ähnliche Funktionen haben und Sie diese möglicherweise für Ihre Zwecke bewerten möchten. Ich diskutiere nur über Perl, da dies die Sprache ist, die ich benutze und mit der ich vertraut bin.
quelle
Wenn Sie Perl auf Ihrem Solaris haben, verwenden Sie es. Andernfalls ist ls mit awk Ihre nächstbeste Wette, da Sie keine Statistik haben oder Ihr Fund kein GNU-Fund ist.
quelle
In Solaris gibt es einen Trick, den ich verwendet habe. Wenn Sie nach der Größe von mehr als einer Datei fragen, wird nur die Gesamtgröße ohne Namen zurückgegeben. Fügen Sie daher eine leere Datei wie / dev / null als zweite Datei hinzu:
zB Befehl fileyouwant / dev / null
Ich kann mich nicht erinnern, welcher Größenbefehl für ls / wc / etc funktioniert - leider habe ich keine Solaris-Box zum Testen.
quelle
Unter Linux, das Sie verwenden können
du -h $FILE
, funktioniert das auch unter Solaris?quelle
Hast du du -ks | ausprobiert? awk '{print $ 1 * 1024}'. Das könnte einfach funktionieren.
quelle