如何从Shell脚本获取远程文件大小?


77

有没有一种方法可以获取远程文件的大小,例如

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

在shell脚本?


此页面上的一些示例,这是Windows Shell脚本的一个示例(可以

1
怎么wget --spider
康拉德(Konrad)

Answers:


114

您可以下载文件并获取其大小。但是我们可以做得更好。

使用curl使用该选项仅获取响应标头-I

在响应标头中查找Content-Length:要跟随其后的文件大小(以字节为单位)。

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

要获取大小,请使用过滤器从上面的输出中提取数字部分:

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

5
使用了此函数,并希望将结果发送到将字节格式化为KB或MB的函数,并且它具有隐藏的回车符,通过管道将结果tr -d '\r'删除。
jClark 2014年

2
curl -sI $URL | grep -i content-length 为了避免区分大小写,您必须-i在grep中使用
arulraj.net 2014年

不为我工作curl -sI https://code.jquery.com/jquery-3.1.1.min.js | grep -i content-length
fguillen

2
使用cut -d''-f2代替awk。awk比cut更大,更慢。需要明确的是,单引号之间是一个空格。否则,此答案对我有用。
囚犯

24

其他答案有两个警告:

  1. 某些服务器没有为HEAD请求返回正确的Content-Length,因此您可能需要完成完整下载。
  2. 除非您指定gzip / deflate标头,否则您可能会得到一个非常大的响应(与现代浏览器相比)。

另外,您可以在没有grep / awk或管道的情况下执行此操作:

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

和相同的压缩请求:

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

这似乎不适用于重定向。这还不下载整个文件吗?
汤姆·黑尔

1
@TomHale我想您可以将其添加-L到命令中以跟随重定向(我没有方便的重定向URL来进行测试)。而且,是的,它下载了整个文件。
James H

2
如果您可以依靠要查询的Web服务器返回准确Content-LengthHEAD请求,则无需下载整个文件。只需添加-I到上面的示例中即可查看它如何返回零(至少在2019年2月25日如此)。我的解决方案更加笼统。
James H

9

codaddict的答案类似,但没有要求grep

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

3
具有讽刺意味的是,您选择的示例URL使用小写的标题字符串content-length,这破坏了您的命令。有很多方法可以忽略awk中的大小写,但这是最有效的方法:curl -sI http://api.twitter.com/1/statuses/public_timeline.json | awk '/[Cc]ontent-[Ll]ength/ { print $2 }'...当然,grep也很好;)
Joel Mellon 2014年

2
我想标题在我的回答和这条评论之间的四年中发生了变化:)
Johnsyweb

5

重定向时,上述答案无效。例如,如果要获得debian iso DVD的大小,则必须使用--location选项,否则,报告的大小可能是302 Moved Temporarily答案正文的大小,而不是实际文件的大小。
假设您具有以下网址:

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

使用curl,您可以获得:

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

这就是为什么我更喜欢使用HEAD,这是libwww-perl软件包(在debian上)lwp-request命令的别名。它的另一个优点是,它去除了多余的\ r字符,从而简化了后续的字符串处理。

因此,要检索debian iso DVD的大小,可以执行例如以下操作:

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

请注意:

  • 此方法仅需要启动一个进程
  • 由于使用了特殊的扩展语法,因此仅适用于bash

对于其他shell,您可能不得不求助于sed,awk,grep等。


好答案。一口气可以做到吗?
cavalcade '26

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

1
抱歉,我不知道如何编辑我之前发布的评论过快。我刚刚发布的单线解决方案可以工作,但要花两个额外的流程。另一方面,它应该与更多的外壳兼容。
ncarrier

5

我认为最简单的方法是:

  1. 使用cURL以静默模式运行-s

  2. 只拉标题-I(以免下载整个文件)

  3. 然后执行不区分大小写的grep -i

  4. 并使用awk返回第二个arg $2

  5. 输出返回为 bytes

例子:

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

//output: 52

要么

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

//output: 86709

要么

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

//output: 1073741824

显示为千字节/兆字节

如果要以千字节为单位显示大小,则将awk更改为:

awk '{print $2/1024}'

或兆字节

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

3

可接受的解决方案不适用于我,这是:

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

1
@fguillen您认为从标头中获取数据更好吗?因为这实际上会将文件缓冲区下载到wc
AO_

@ 0x616f您是正确的,此信息也位于标题中。您能提出解决方案并引起我注意吗?我会投票通过;)
fguillen

1

我有一个基于codaddict的answer的shell函数,该函数因此以人类可读的格式给出了远程文件的大小:

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

结合以上所有对我的作品:

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

这将仅返回内容长度(以字节为单位):

3767500800

-1

我这样使用([Cc]ontent-[Ll]ength:),因为我在标题响应中让服务器提供了多个Content-Length字符

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

这将向您显示有关正在进行的下载的详细信息

您只需要指定一个网址,如下例所示。

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

输出

  % 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

为了实现自动化目的,您只需将命令添加到脚本文件中。


-5

不同的解决方案:

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

为您提供KB大小


1
仅当我们在托管url内容的同一服务器上拥有ssh帐户时,此方法才有效,这是一个很严格的约束。
菲利普
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.