Ermittelt die gesamte Dateigröße aus einer Datei, die eine Dateiliste enthält

14

Ich habe eine Datei mit einer Liste von Dateien, deren Gesamtgröße ich wissen möchte. Gibt es einen Befehl dazu?

Mein Betriebssystem ist ein sehr einfaches Linux (Qnap TS-410).

BEARBEITEN:

Ein paar Zeilen aus der Akte:

/ share / archive / Bailey Test / BD006 / 0.tga
/ share / archive / Bailey / BD007 / 1 Version 1.tga
/ share / archive / Bailey 2 / BD007 / example.tga

Nicolas
quelle
Geben Sie uns ein paar Beispielzeilen der Datei.
EEAA
Beispiel aus der Datei hinzugefügt.
Nicolas
Das ist eine Art NAS, oder? Hast du eine Busybox installiert?
cjc
Ja, und ich denke, es ist bereits installiert. Warum?
Nicolas

Antworten:

13

Ich glaube so etwas würde in busybox funktionieren:

du `cat filelist.txt` | awk '{i+=$1} END {print i}'

Ich habe nicht die gleiche Umgebung wie Sie, aber wenn Sie auf Probleme mit Leerzeichen in Dateinamen stoßen, funktioniert auch Folgendes:

cat filelist.txt | while read file;do
  du "$file"
done | awk '{i+=$1} END {print i}'

Edit 1 :
@stew ist direkt in seinem Post unten, du zeigt die Festplattennutzung und nicht die genaue Dateigröße. Um das Verhalten zu ändern, verwendet busybox das Flag -a. Versuchen Sie also, die du -a "$file"genaue Dateigröße zu ermitteln und die Ausgabe / das Verhalten zu vergleichen.

Mattias Ahnberg
quelle
1
Vielen Dank für Ihre Eingabe, der erste Befehl wird zurückgegeben /usr/bin/du: Argument list too long(fast 80.000 Zeilen in meiner Datei). Ihr zweiter Befehl gibt mir nur eine Eingabeaufforderung, sobald ich die Eingabetaste drücke und auf etwas mehr warte?
Nicolas
Schwer zu sagen mit deiner Umgebung. Handelt es sich um die normale Eingabeaufforderung oder nur um eine blinkende Eingabeaufforderung? Wenn es das letztere ist, kann es langsam sein, auf das Ergebnis zu warten. Wenn es sich um eine Eingabeaufforderung handelt, kann es sein, dass Sie ein Zeichen verpasst haben? Und wenn es eine normale Eingabeaufforderung ist, die ich nicht kenne, habe ich sie gründlich getestet, bevor ich sie getippt habe. :(
Mattias Ahnberg
Es ist eine Eingabeaufforderung, wenn ich Folgendes tue cat tgafiles.txt | while read file;do du "$file" done | awk '{i+=$1} END {print i}'. danke mattias
Nicolas
1
Ah! Wenn Sie alles in eine Zeile setzen, brauchen Sie eine andere; wie folgt: cat tgafiles.txt | while read file;do du "$file";done | awk '{i+=$1} END {print i}'(dh vor getan).
Mattias Ahnberg
Spot on! Es hat perfekt funktioniert, Prost! (obwohl ich diesen Fehler selbst hätte herausfinden können)
Nicolas
8
du -c `cat filelist.txt` | tail -1 | cut -f 1

-cfügt die Zeile "Gesamtgröße" hinzu;
tail -1nimmt die letzte Zeile (mit der Gesamtgröße);
cut -f 1schneidet das Wort "total" aus.

olegzhermal
quelle
Dies schlägt fehl, wenn die Liste der Argumente zu lang ist. Meine Dateiliste ist groß. Die folgende Antwort mit xargs scheint die einfachste Lösung zu sein.
Syclone0044
4

Ich weiß nicht, ob Ihre Linux-Tools dazu in der Lage sind, aber:

cat /tmp/filelist.txt  |xargs -d \\n du -c

Wenn Sie dies tun, setzen die Xargs das Trennzeichen auf ein Newline-Zeichen und du erstellt eine Gesamtsumme für Sie.

Unter http://busybox.net/downloads/BusyBox.html scheint "busybox du" die Option "Gesamtsumme" zu unterstützen, "busybox xargs" unterstützt jedoch keine benutzerdefinierten Begrenzer.

Auch hier bin ich mir nicht sicher, was dein Toolset angeht.

cjc
quelle
Hier ist das Ergebnis:xargs: invalid option -- d
Nicolas
Genial: Die Arbeit mit dem Busybox-Linux eines NAS ist wie eine McGuyver-Episode, bei der versucht wird, ein funktionierendes Flugzeug aus Segeltuch, Stöcken und Bindfäden zu bauen.
cjc
Wie wäre es damit, wenn Sie den Platz dafür auf einem anderen Computer haben: Kopieren Sie alle Dateien, die Sie interessieren, auf ein anderes, voll funktionsfähiges Linux und führen Sie dann dort Stews Lösung aus. Dies könnte viel einfacher sein, als herauszufinden, ob busybox dazu in der Lage ist.
cjc
1
Ich denke, die Antwort ist die beste. Es ist prägnant und geht viel schneller als die anderen Antworten in diesem Thread.
Zymhan
Gute Antwort. Sie sollten weglassen , -cda xargs mehrere Aufrufe duausführt , wenn die Dateiliste lang genug ist und mehrere duSummen erzeugt.
Qwr
4
while read filename ;  do stat -c '%s' $filename ; done < filelist.txt | awk '{total+=$1} END {print total}'

Dies ähnelt der Lösung von Mattias Ahnberg. Die Verwendung von "read" umgeht Probleme mit Dateinamen / Verzeichnissen mit Leerzeichen. Ich benutze statstattdessen du, um die Dateigröße zu bekommen. du erhält die Menge an Speicherplatz auf der Festplatte anstelle der Dateigröße, die möglicherweise unterschiedlich ist. Abhängig von Ihrem Dateisystem belegt eine 1-Byte-Datei immer noch 4 KB Festplattenspeicher (oder unabhängig von der Blockgröße). Also für eine 1-Byte-Datei sagt stat 1 Byte und du sagt 4k.

Eintopf
quelle
Guter Kommentar zu filesize vs disksize!
Mattias Ahnberg
Sehr interessanter Kommentar in der Tat, leider kennt mein Linux den statBefehl nicht:stat: command not found
Nicolas
Möglicherweise müssen Sie "busybox stat" sagen.
cjc
es heißt stat: applet not foundin diesem Fall
Nicolas
4

Hier ist eine andere Lösung für das Problem:

cat filelist.txt | tr '\n' '\0' | wc -c --files0-from=-
dsamarin
quelle
Für mich (auf Cygwin) du -bcläuft das viel schneller.
Qwr
2

Versuchen Sie so etwas:

$ cat filelist.txt | xargs ls -l | awk '{x+=$5} END {print "total bytes: " x}' 

So gehen Sie richtig mit Leerzeichen in Pfaden um:

$ find /path/to/files -type f -print0 | xargs -0 ls -l | awk '{x+=$5} END {print "total bytes: " x}' 
EEAA
quelle
Vielen Dank für Ihre Eingabe. Leider gibt es ein Problem damit, dass die Leerzeichen in den Verzeichnissen in meiner Datei nicht mit einem "\" maskiert werden. Daher bricht es beim Durchlaufen der Dateiliste ab.
Nicolas
Können Sie die Liste der Textdateien umgehen und diese einfach aus der Ausgabe von generieren find?
EEAA
Leider ist die Liste zu lang, es gibt 79159 Zeilen mit Dateien (vollständiger Pfad), deshalb habe ich sie in eine Datei ausgegeben. Vielleicht kann ich ein Argument hinzufügen, um dem Ergebnis des Funds zu entkommen.
Nicolas
Es gibt kein "-print0" Argument mit dem Fund auf meinem Linux-System
Nicolas
@Nicolas - das liegt daran, dass findanstelle der echten findBinärdatei eine reduzierte Busybox verwendet wird .
EEAA
1

cat docs.txt | xargs -d \\n du -sk | awk '{total+=$1} END{print total}'

Pradeep
quelle