Wie erhalte ich die Größe einer entfernten Datei aus einem Shell-Skript?

76

Gibt es eine Möglichkeit, die Größe einer Remote-Datei wie zu erhalten

http://api.twitter.com/1/statuses/public_timeline.json

im Shell-Skript?

Ernst
quelle
Einige Beispiele in dieser Seite ist hier ein für Windows - Shell - Skript (das kann mit wenige Modifikation als Bash - Skript doppelt so hoch sein) superuser.com/a/1007898/429721
1
Wie wäre es wget --spider?
Konrad

Antworten:

113

Sie können die Datei herunterladen und ihre Größe erhalten. Aber wir können es besser machen.

Verwenden Sie curl , um mit der Option nur den Antwortheader abzurufen-I .

Suchen Sie im Antwortheader nach Content-Length:der Größe der Datei in Byte.

$ URL="http://api.twitter.com/1/statuses/public_timeline.json"
$ curl -sI $URL | grep -i Content-Length
Content-Length: 134

Um die Größe zu ermitteln, verwenden Sie einen Filter, um den numerischen Teil aus der obigen Ausgabe zu extrahieren:

$ curl -sI $URL | grep -i Content-Length | awk '{print $2}'
134
Codaddict
quelle
5
Verwendete diese Funktion und wollte das Ergebnis an eine Funktion senden, um die Bytes in KB oder MB zu formatieren, und es hat einen versteckten Wagenrücklauf, leiten Sie das Ergebnis weiter tr -d '\r', um sie zu entfernen.
jClark
2
curl -sI $URL | grep -i content-length Um Groß- und Kleinschreibung zu vermeiden, müssen Sie -iin grep
arulraj.net
Ich arbeite nicht für michcurl -sI https://code.jquery.com/jquery-3.1.1.min.js | grep -i content-length
fguillen
2
Verwenden Sie cut -d '' -f2 anstelle von awk. awk ist größer und langsamer als geschnitten. Und um klar zu sein, das ist ein Leerzeichen zwischen einfachen Anführungszeichen. Ansonsten funktioniert diese Antwort bei mir.
Gefangener 13
24

Zwei Vorbehalte zu den anderen Antworten:

  1. Einige Server geben nicht die richtige Inhaltslänge für eine HEAD-Anforderung zurück, daher müssen Sie möglicherweise den vollständigen Download durchführen.
  2. Sie erhalten wahrscheinlich eine unrealistisch große Antwort (im Vergleich zu einem modernen Browser), wenn Sie keine gzip / deflate-Header angeben.

Sie können dies auch ohne grep / awk oder Piping tun:

curl 'http://api.twitter.com/1/statuses/public_timeline.json' --location --silent --write-out 'size_download=%{size_download}\n' --output /dev/null

Und die gleiche Anfrage mit Komprimierung:

curl 'http://api.twitter.com/1/statuses/public_timeline.json' --location --silent  -H 'Accept-Encoding: gzip,deflate' --write-out 'size_download=%{size_download}\n' --output /dev/null
James H.
quelle
Dies scheint bei Weiterleitungen nicht zu funktionieren. Lädt dies nicht auch die gesamte Datei herunter?
Tom Hale
1
@ TomHale Ich denke, Sie können einfach -Lzum Befehl hinzufügen , um Weiterleitungen zu folgen (ich habe keine praktische Weiterleitungs-URL zum Testen). Und ja, es lädt die gesamte Datei herunter.
James H
2
Wenn Sie auf dem Webserver abhängen können Sie eine genaue Rückkehr sind Abfragen Content-Lengthfür eine HEADAnfrage, brauchen Sie nicht die ganze Datei zum Download bereit . -IFügen Sie einfach das obige Beispiel hinzu, um zu sehen, wie es Null zurückgibt (zumindest am 25.02.2019). Meine Lösung ist allgemeiner.
James H
9

Ähnlich wie die Antwort von codaddict , jedoch ohne den Aufruf an grep:

curl -sI http://api.twitter.com/1/statuses/public_timeline.json | awk '/Content-Length/ { print $2 }'
Johnsyweb
quelle
3
Ironischerweise verwendet die von Ihnen ausgewählte Beispiel-URL Kleinbuchstaben, content-lengthwodurch Ihr Befehl unterbrochen wird. Es gibt viele Möglichkeiten, Groß- und Kleinschreibung in awk zu ignorieren, aber dies ist die kugelsicherste: curl -sI http://api.twitter.com/1/statuses/public_timeline.json | awk '/[Cc]ontent-[Ll]ength/ { print $2 }'... natürlich ist grep auch nett;)
Joel Mellon
2
Ich denke, dass sich die Überschriften in den vier Jahren zwischen meiner Antwort und diesem Kommentar
geändert haben
5

Die vorhergehenden Antworten funktionieren nicht, wenn Umleitungen vorhanden sind. Wenn Sie beispielsweise die Größe der Debian-ISO-DVD wünschen, müssen Sie die Option --location verwenden. Andernfalls kann die gemeldete Größe die des 302 Moved TemporarilyAntwortkörpers und nicht die der realen Datei sein.
Angenommen, Sie haben die folgende URL:

$ url=http://cdimage.debian.org/debian-cd/8.1.0/amd64/iso-dvd/debian-8.1.0-amd64-DVD-1.iso

Mit Curl könnten Sie erhalten:

$ curl --head --location ${url}
HTTP/1.0 302 Moved Temporarily
...
Content-Type: text/html; charset=iso-8859-1
...

HTTP/1.0 200 OK
...
Content-Length: 3994091520
...
Content-Type: application/x-iso9660-image
...

Aus diesem Grund bevorzuge ich die Verwendung HEADeines Alias ​​für den lwp-requestBefehl aus dem libwww-perl- Paket (auf Debian). Ein weiterer Vorteil hat, dass es die zusätzlichen Streifen \ r Zeichen, die nachfolgende Kettenverarbeitung erleichtert.

Um die Größe der Debian-ISO-DVD abzurufen, könnte man zum Beispiel Folgendes tun:

$ size=$(HEAD ${url})
$ size=${size##*Content-Length: }
$ size=${size%%[[:space:]]*}

Bitte beachte, dass:

  • Für diese Methode muss nur ein Prozess gestartet werden
  • Aufgrund der speziellen verwendeten Erweiterungssyntax funktioniert es nur mit Bash

Für andere Muscheln müssen Sie möglicherweise auf sed, awk, grep et al. Zurückgreifen.

Träger
quelle
Gute Antwort. Wäre es möglich, dies in einem Einzeiler zu tun?
Kavalkade
size = $ (HEAD $ {url} | grep "
Inhaltslänge
1
Entschuldigung, ich weiß nicht, wie ich meinen vorherigen Kommentar bearbeiten soll, den ich zu schnell gepostet habe. Die soeben veröffentlichte Einzeilerlösung funktioniert, jedoch auf Kosten der Erstellung von zwei zusätzlichen Prozessen. Andererseits sollte es mit mehr Muscheln kompatibel sein.
Träger
5

Ich denke, der einfachste Weg, dies zu tun, wäre:

  1. Verwenden Sie cURL, um im stillen Modus zu laufen -s.

  2. Ziehen Sie nur die Header -I(um zu vermeiden, dass die gesamte Datei heruntergeladen wird).

  3. dann mache einen case unempfindlichen grep -i

  4. und gib das zweite Argument mit awk zurück $2.

  5. Ausgabe wird zurückgegeben als bytes

Beispiele:

curl -sI http://api.twitter.com/1/statuses/public_timeline.json | grep -i content-length | awk '{print $2}'

//output: 52

oder

curl -sI https://code.jquery.com/jquery-3.1.1.min.js | grep -i content-length | awk '{print $2}'

//output: 86709

oder

curl -sI http://download.thinkbroadband.com/1GB.zip | grep -i content-length | awk '{print $2}'

//output: 1073741824

Als Kilobyte / Megabyte anzeigen

Wenn Sie die Größe in Kilobyte anzeigen möchten, ändern Sie die awk in:

awk '{print $2/1024}'

oder Megabyte

awk '{print $2/1024/1024}'
AO_
quelle
3

Die akzeptierte Lösung hat bei mir nicht funktioniert. Dies ist:

curl -s https://code.jquery.com/jquery-3.1.1.min.js | wc -c
fguillen
quelle
1
@fguillen Glaubst du nicht, es ist besser, die Daten aus den Headern zu bekommen? Da dies tatsächlich den Dateipuffer in herunterladen wird wc.
AO_
@ 0x616Wenn Sie Recht haben, befinden sich diese Informationen auch in den Kopfzeilen. Können Sie eine Lösung vorschlagen und mich bemerken? Ich werde darüber abstimmen;)
fguillen
1

Ich habe eine Shell-Funktion, die auf der Antwort von codaddict basiert und die Größe einer entfernten Datei in einem für Menschen lesbaren Format ergibt:

remote_file_size () {
  printf "%q" "$*"           |
    xargs curl -sI           |
    grep Content-Length      |
    awk '{print $2}'         |
    tr -d '\040\011\012\015' |
    gnumfmt --to=iec-i --suffix=B # the `g' prefix on `numfmt' is only for systems
  # ^                             # that lack the GNU coreutils by default, i.e.,
  # |                             # non-Linux systems
  # |
  # |                             # in other words, if you're on Linux, remove this
  # |                             # letter `g'; if you're on BSD or Mac, install the GNU coreutils
} # |                                        |
  # +----------------------------------------+
BIP2
quelle
1

All das für mich zu kombinieren funktioniert:

URL="http://cdimage.debian.org/debian-cd/current/i386/iso-dvd/debian-9.5.0-i386-DVD-1.iso"
curl --head --silent --location "$URL" | grep -i "content-length:" | tr -d " \t" | cut -d ':' -f 2

Dies gibt nur die Inhaltslänge in Bytes zurück:

3767500800
Tom Freudenberg
quelle
-1

Ich benutze dies ([Cc]ontent-[Ll]ength:), weil ich Server bekommen habe, die bei der Header-Antwort mehrere Content-Length-Zeichen geben

curl -sI "http://someserver.com/hls/125454.ts" | grep [Cc]ontent-[Ll]ength: | awk '{ print $2 }'

Accept-Ranges: bytes Access-Control-Expose-Headers: Date, Server, Content-Type, Content-Length Server: WowzaStreamingEngine/4.5.0 Cache-Control: no-cache Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: OPTIONS, GET, POST, HEAD Access-Control-Allow-Headers: Content-Type, User-Agent, If-Modified-Since, Cache-Control, Range Date: Tue, 10 Jan 2017 01:56:08 GMT Content-Type: video/MP2T Content-Length: 666460

Fathur Rohim
quelle
-1

Dies zeigt Ihnen detaillierte Informationen zum laufenden Download

Sie müssen nur eine URL wie im folgenden Beispiel angeben.

$ curl -O -w 'We downloaded %{size_download} bytes\n' 
https://cmake.org/files/v3.8/cmake-3.8.2.tar.gz

Ausgabe

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 7328k  100 7328k    0     0   244k      0  0:00:29  0:00:29 --:--:--  365k
We downloaded 7504706 bytes

Für automatisierte Zwecke müssen Sie nur den Befehl zu Ihrer Skriptdatei hinzufügen.

Ali
quelle
-5

andere Lösung:

ssh userName@IP ls -s PATH | grep FILENAME | awk '{print$1}'

gibt Ihnen die Größe in KB

Ortal Turgeman
quelle
1
Dies funktioniert nur, wenn wir ein SSH-Konto auf demselben Server haben, auf dem der URL-Inhalt gehostet wird. Dies ist eine recht starke Einschränkung.
G Philip