it-swarm.com.de

Portable Weg, um die Dateigröße (in Bytes) in der Shell zu bekommen?

Unter Linux verwende ich stat --format="%s" FILE, aber Solaris, auf das ich Zugriff habe, verfügt nicht über den Befehl stat. Was soll ich dann verwenden?

Ich schreibe Bash-Skripte und kann keine neue Software auf dem System installieren.

Ich habe darüber nachgedacht, bereits Folgendes zu verwenden:

Perl -e '@x=stat(shift);print $x[7]' FILE

oder auch:

ls -nl FILE | awk '{print $5}'

Aber beides macht keinen Sinn - Perl nur ausführen, um die Dateigröße zu ermitteln? Oder 2 Befehle ausführen, um dasselbe zu tun?

106
user80168

wc -c < filename (Abkürzung für Word Count, -c Gibt die Byteanzahl aus) ist eine tragbare POSIX Lösung. Nur das Ausgabeformat ist möglicherweise plattformübergreifend nicht 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 Byteanzahl gedruckt.

Ich befürchtete, dass es nicht für Binärdateien funktionieren würde, aber es funktioniert sowohl unter Linux als auch unter Solaris. Sie können es mit wc -c < /usr/bin/wc Versuchen. Darüber hinaus sind POSIX-Dienstprogramme für den Umgang mit Binärdateien garantiert , sofern nicht ausdrücklich anders angegeben.

195
Carl Smotricz

Am Ende habe ich mein eigenes Programm (wirklich klein) geschrieben, 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

Meiner Meinung nach sind die zwei saubersten Methoden für gängige Linux-Tools:

$ stat -c %s /usr/bin/stat
50000

$ wc -c < /usr/bin/wc
36912

Aber ich möchte einfach keine Parameter eingeben oder die Ausgabe weiterleiten, nur um eine Dateigröße zu erhalten, also verwende ich meine eigene BFS-Größe.

35
fwhacking

Obwohl du normalerweise die Festplattenauslastung und nicht die tatsächliche Datengröße ausgibt, kann GNU coreutils du die "scheinbare Größe" der Datei in Bytes ausgeben:

du -b FILE

Aber es funktioniert nicht unter BSD, Solaris, MacOS, ...

23
fwhacking

Schließlich habe ich mich für ls und die Bash-Array-Erweiterung entschieden:

TEMP=( $( ls -ln FILE ) )
SIZE=${TEMP[4]}

es ist nicht wirklich nett, aber es macht wenigstens nur 1 Fork + Execve und es ist nicht auf eine sekundäre Programmiersprache angewiesen (Perl/Ruby/Python/was auch immer)

13
user80168

Plattformübergreifende schnellste Lösung (verwendet nur single fork () für ls, versucht nicht, die tatsächlichen Zeichen zu zählen, erzeugt keine nicht benötigten awk, Perl usw.).

Getestet unter MacOS, Linux - unter Solaris sind möglicherweise geringfügige Änderungen erforderlich:

__ln=( $( ls -Lon "$1" ) )
__size=${__ln[3]}
echo "Size is: $__size bytes"

Vereinfachen Sie bei Bedarf ls Argumente und passen Sie den Offset in $ {__ ln [3]} an.

Hinweis: Folgen Sie symlinks.

8
Orwellophile

BSDs haben stat mit anderen Optionen als die Coreutils GNU), aber ähnlichen Fähigkeiten.

stat -f %z <file name> 

Dies funktioniert unter macOS (getestet am 10.12), FreeBSD , NetBSD und OpenBSD .

7
user7504315

Wenn Sie find from GNU fileutils verwenden:

size=$( find . -maxdepth 1 -type f -name filename -printf '%s' )

Leider unterstützen andere Implementierungen von find-maxdepth, Noch -printf. Dies ist der Fall für z.B. Solaris und macOS find.

4

Bei der Verarbeitung der ls -n - Ausgabe können Sie als Alternative zu nicht tragbaren 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.

getsize() { set -- $(ls -dn "$1") && echo $5; }
getsize FILE

Dies teilt die Ausgabe von ln -dn Gemäß den aktuellen Einstellungen der Umgebungsvariablen IFS auf, weist sie Positionsargumenten zu und gibt die fünfte wieder. Mit -d Wird sichergestellt, dass Verzeichnisse ordnungsgemäß behandelt werden, und mit -n Wird sichergestellt, dass Benutzer- und Gruppennamen im Gegensatz zu -l Nicht aufgelöst werden müssen. Außerdem können Benutzer- und Gruppennamen, die Leerzeichen enthalten, theoretisch die erwartete Zeilenstruktur sprengen. Sie sind normalerweise nicht erlaubt, aber diese Möglichkeit lässt den Programmierer dennoch innehalten und nachdenken.

4
Richard

Sie können den Befehl find verwenden, um einige Dateien abzurufen (hier werden temporäre Dateien extrahiert). Anschließend können Sie den Befehl du verwenden, um die Dateigröße jeder Datei mit dem Schalter -h In lesbarer Form abzurufen.

find $HOME -type f -name "*~" -exec du -h {} \;

AUSGABE:

4.0K    /home/turing/Desktop/JavaExmp/TwoButtons.Java~
4.0K    /home/turing/Desktop/JavaExmp/MyDrawPanel.Java~
4.0K    /home/turing/Desktop/JavaExmp/Instream.Java~
4.0K    /home/turing/Desktop/JavaExmp/RandomDemo.Java~
4.0K    /home/turing/Desktop/JavaExmp/Buff.Java~
4.0K    /home/turing/Desktop/JavaExmp/SimpleGui2.Java~
3
Abhishek Singh

Ihr erstes Perl-Beispiel erscheint mir nicht unangemessen.

Aus diesen Gründen bin ich vom Schreiben von Shell-Skripten (in bash/sh usw.) zum Schreiben aller bis auf die trivialsten Skripten in Perl übergegangen. Ich stellte fest, dass ich Perl für bestimmte Anforderungen starten musste, und als ich das immer öfter tat, stellte ich fest, dass das Schreiben der Skripte in Perl wahrscheinlich leistungsfähiger war (in Bezug auf die Sprache und die breite Palette von Bibliotheken, die verfügbar sind über - CPAN ) und effizienter Weg, um das zu erreichen, was ich wollte.

Beachten Sie, dass andere Shell-Skriptsprachen (z. B. Python/Ruby) zweifellos über ähnliche Funktionen verfügen. Sie können diese für Ihre Zwecke auswerten. Ich diskutiere nur über Perl, da dies die Sprache ist, die ich verwende und mit der ich vertraut bin.

2
Brian Agnew