Làm cách nào để lấy kích thước tệp từ xa từ tập lệnh shell?


78

Có cách nào để lấy kích thước của tệp từ xa như

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

trong tập lệnh shell?


một vài ví dụ trong trang này, đây là một cho tập lệnh shell dành cho Windows (có thể gấp đôi như tập lệnh bash với một vài sửa đổi) superuser.com/a/1007898/429721

1
Làm thế nào về wget --spider?
Konrad

Câu trả lời:


117

Bạn có thể tải xuống tệp và lấy kích thước của nó. Nhưng chúng ta có thể làm tốt hơn.

Sử dụng curl để chỉ nhận tiêu đề phản hồi bằng cách sử dụng -Itùy chọn.

Trong tiêu đề phản hồi, tìm kiếm Content-Length:sẽ được theo sau là kích thước của tệp tính bằng byte.

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

Để có được kích thước, hãy sử dụng bộ lọc để trích xuất phần số từ đầu ra ở trên:

$ curl -sI $URL | grep -i Content-Length | awk '{print $2}'
134

5
Đã sử dụng hàm này và muốn gửi kết quả đến một hàm để định dạng các byte thành KB hoặc MB và nó có một ký tự xuống dòng ẩn, hãy nhập kết quả tr -d '\r'để loại bỏ chúng.
jClark

2
curl -sI $URL | grep -i content-length để tránh trường hợp nhạy cảm, bạn phải sử dụng -itrong grep
arulraj.net

Không làm việc cho tôicurl -sI https://code.jquery.com/jquery-3.1.1.min.js | grep -i content-length
fguillen

2
Sử dụng cut -d '' -f2 thay vì awk. awk lớn hơn và chậm hơn cắt. Và rõ ràng hơn, đó là khoảng cách giữa các dấu nháy đơn. Nếu không, câu trả lời này phù hợp với tôi.
Prisoner

24

Hai lưu ý cho các câu trả lời khác:

  1. Một số máy chủ không trả về Độ dài Nội dung chính xác cho yêu cầu HEAD, vì vậy bạn có thể cần tải xuống toàn bộ.
  2. Bạn có thể sẽ nhận được phản hồi lớn không thực tế (so với trình duyệt hiện đại) trừ khi bạn chỉ định tiêu đề gzip / deflate.

Ngoài ra, bạn có thể làm điều này mà không cần grep / awk hoặc piping:

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

Và yêu cầu tương tự với nén:

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

Điều này dường như không hoạt động với chuyển hướng. Điều này cũng không tải xuống toàn bộ tệp?
Tom Hale,

1
@TomHale Tôi nghĩ bạn có thể chỉ cần thêm -Lvào lệnh để theo dõi chuyển hướng (Tôi không có URL chuyển hướng tiện dụng để kiểm tra). Và, có, nó tải xuống toàn bộ tệp.
James H

2
Nếu bạn có thể phụ thuộc vào máy chủ web mà bạn đang truy vấn để trả về Content-Lengthmột HEADyêu cầu chính xác , bạn không cần phải tải xuống toàn bộ tệp. Chỉ cần thêm -Ivào ví dụ trên để xem nó trả về 0 như thế nào (ít nhất là vào ngày 25 tháng 2 năm 2019). Giải pháp của tôi là khái quát hơn.
James H

9

Tương tự như câu trả lời của codaddict , nhưng không có lệnh gọi đến grep:

curl -sI http://api.twitter.com/1/statuses/public_timeline.json | awk '/Content-Length/ { print $2 }'

3
Trớ trêu thay, URL mẫu bạn đã chọn sử dụng các chuỗi tiêu đề chữ thường content-lengthlàm hỏng lệnh của bạn. Có rất nhiều cách để bỏ qua trường hợp trong awk, nhưng đây là đạn nhất: curl -sI http://api.twitter.com/1/statuses/public_timeline.json | awk '/[Cc]ontent-[Ll]ength/ { print $2 }'... tất nhiên grep cũng là tốt đẹp;)
Joel Mellon

2
Tôi đoán rằng các tiêu đề thay đổi trong bốn năm giữa câu trả lời của tôi và nhận xét này :)
Johnsyweb

5

Các câu trả lời trước sẽ không hoạt động khi có chuyển hướng. Ví dụ, nếu một người muốn kích thước của đĩa DVD debian iso, anh ta phải sử dụng tùy chọn --location, nếu không, kích thước được báo cáo có thể là kích thước của phần 302 Moved Temporarilytrả lời, không phải của tệp thực.
Giả sử bạn có url sau:

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

Với curl, bạn có thể có được:

$ 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
...

Đó là lý do tại sao tôi thích sử dụng hơn HEAD, đây là một bí danh cho lwp-requestlệnh từ gói libwww-perl (trên debian). Một ưu điểm khác của nó là nó loại bỏ các ký tự \ r thừa , giúp giảm bớt quá trình xử lý chuỗi tiếp theo.

Vì vậy, để truy xuất kích thước của đĩa DVD debian iso, người ta có thể làm ví dụ:

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

Xin lưu ý rằng:

  • phương pháp này sẽ chỉ yêu cầu khởi chạy một quy trình
  • nó sẽ chỉ hoạt động với bash, vì cú pháp mở rộng đặc biệt được sử dụng

Đối với các shell khác, bạn có thể phải dùng đến sed, awk, grep và cộng sự.


Câu trả lời hay đấy. Nó có thể làm điều đó trong một lớp lót không?
cavalcade

size = $ (HEAD $ {url} | grep "Content-Length:" | sed 's /.*: //')
ncarrier

1
Xin lỗi, tôi không biết làm thế nào để chỉnh sửa nhận xét trước đây của mình mà tôi đã đăng quá nhanh. Giải pháp một lớp lót mà tôi vừa đăng sẽ hoạt động nhưng với chi phí tạo ra 2 quy trình bổ sung. Mặt khác, nó phải tương thích với nhiều shell hơn.
ncarrier

5

Tôi nghĩ cách dễ nhất để làm điều này là:

  1. sử dụng cURL để chạy ở chế độ im lặng -s,

  2. chỉ kéo các tiêu đề -I(để tránh tải xuống toàn bộ tệp)

  3. sau đó thực hiện một grep không phân biệt chữ hoa chữ thường -i

  4. và trả về đối số thứ hai bằng awk $2.

  5. đầu ra được trả lại dưới dạng bytes

Ví dụ:

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

//output: 52

hoặc là

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

//output: 86709

hoặc là

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

//output: 1073741824

Hiển thị dưới dạng Kilobyte / Megabyte

Nếu bạn muốn hiển thị kích thước bằng Kilobyte thì hãy thay đổi awk thành:

awk '{print $2/1024}'

hoặc Megabyte

awk '{print $2/1024/1024}'

3

Giải pháp được chấp nhận không hoạt động đối với tôi, đây là:

curl -s https://code.jquery.com/jquery-3.1.1.min.js | wc -c

1
@fguillen Bạn không nghĩ lấy dữ liệu từ tiêu đề sẽ tốt hơn sao? Vì điều này sẽ thực sự tải xuống bộ đệm tệp wc.
AO_ Ngày

@ 0x616f của bạn đúng, thông tin này cũng nằm trong tiêu đề. Bạn có thể đề xuất một giải pháp và thông báo cho tôi? Tôi sẽ bình chọn nó;)
fguillen

1

Tôi có một hàm shell, dựa trên câu trả lời của codaddict , cung cấp kích thước tệp từ xa ở định dạng con người có thể đọc được do đó:

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
} # |                                        |
  # +----------------------------------------+

1

Để kết hợp tất cả các công việc trên cho tôi:

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

Điều này sẽ chỉ trả về độ dài nội dung tính bằng byte:

3767500800

-1

Tôi sử dụng như thế này ([Cc]ontent-[Ll]ength:), vì tôi nhận được máy chủ cung cấp nhiều ký tự Độ dài Nội dung ở phản hồi tiêu đề

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


-1

Điều này sẽ hiển thị cho bạn thông tin chi tiết về quá trình tải xuống đang diễn ra

bạn chỉ cần chỉ định một URL như ví dụ dưới đây.

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

đầu ra

  % 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

Đối với các mục đích tự động, bạn chỉ cần thêm lệnh vào tệp script của mình.


-5

giải pháp khác nhau:

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

cung cấp cho bạn kích thước tính bằng KB


1
Điều này chỉ hoạt động nếu chúng tôi có tài khoản ssh trên cùng một máy chủ nơi lưu trữ nội dung url, đây là một hạn chế khá mạnh.
G Philip
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.