Wie kann ich die Größe einer Datei in einem Bash-Skript ermitteln?

246

Wie kann ich die Größe einer Datei in einem Bash-Skript ermitteln?

Wie ordne ich dies einer Bash-Variablen zu, damit ich sie später verwenden kann?

haunted85
quelle
1
Koppeln Sie dies mit pvund catfür einen Kopierbefehl, der den Fortschritt und die ETA anzeigt :)
sudo
stat -c% s dateiname
neverMind9

Antworten:

242

Ihre beste Wahl, wenn Sie auf einem GNU-System arbeiten:

stat --printf="%s" file.any

Von mann stat :

% s Gesamtgröße in Byte

In einem Bash-Skript:

#!/bin/bash
FILENAME=/home/heiko/dummy/packages.txt
FILESIZE=$(stat -c%s "$FILENAME")
echo "Size of $FILENAME = $FILESIZE bytes."

HINWEIS: Informationen zur Verwendung von stat im Terminal unter Mac OS X finden Sie in der Antwort von @ chbrown.

b01
quelle
7
@ 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.

Nemo
quelle
48
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.txt
    1160 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.

size="$(wc -c <"$filename")"
Eugéne
quelle
30
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.
  • ... die FORMATE Sektion ...
  • z: Die Größe der Datei in Bytes.

Also alles zusammen jetzt:

stat -f%z myfile1.txt
chbrown
quelle
28

Kommt darauf an, was du mit Größe meinst .

size=$(wc -c < "$file")

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.

In chronologischer Reihenfolge gibt es:

  • IRIXstat (90er Jahre):

    stat -qLs -- "$file"

    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.

  • zsh stateingebaut (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 zsh stat.

  • BSDsstat (2002):

    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:

LC_ALL=C istat "$file" | awk 'NR == 4 {print $5}'

(danke @JeffSchaller für die Hilfe beim Herausfinden der Details ).

In tcsh:

@ size = -Z $file:q

(Größe nach Symlinkauflösung)

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 BLKGETSIZE64 ioctl()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, FIONREAD ioctl()nachdem Sie die Pipe geöffnet haben (im Lese- und Schreibmodus, um ein Hängen zu vermeiden):

fuser -s -- "$fifo_file" && 
  perl -le 'require "sys/ioctl.ph";
            ioctl(STDIN, &FIONREAD, $n) or die$!;
            print unpack "L", $n' <> "$fifo_file"

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).
  • 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"
Stéphane Chazelas
quelle
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.

Dieses Skript enthält eine Produktionsversion mit mehr Hilfe und mehr Optionen: https://github.com/SixArm/file-size

joelparkerhenderson
quelle
9

stat scheint dies mit den wenigsten Systemaufrufen zu tun:

$ 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

quelle
8

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:

-rw-r--r-- 1 user owner 1985 2011-07-12 16:48 index.php

Bearbeiten: Dies ist anscheinend nicht so zuverlässig wie der statBefehl.

Druckles
quelle
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.

Teddy
quelle
2
das oder stat -c "%s";)
1
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.

Oligofren
quelle
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.

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] }')

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 .

findrbot_admin
quelle
1
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.

Inian
quelle
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.

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

BZT
quelle
1
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
Peter Cordes
-1

Die schnellste und einfachste Methode (IMO) ist:

bash_var=$(stat -c %s /path/to/filename)
WinEunuuchs2Unix
quelle
2
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 .
WinEunuuchs2Unix