如何从wget输出中获取下载速度?

7

我需要用wget下载多个文件并测量下载速度。

例如,我可以使用以下命令进行下载:

wget -O /dev/null http://ftp.bit.nl/pub/OpenBSD/4.7/i386/floppy47.fs http://ftp.bit.nl/pub/OpenBSD/4.7/i386/floppyB47.fs

输出结果为

--2010-10-11 18:56:00--  http://ftp.bit.nl/pub/OpenBSD/4.7/i386/floppy47.fs
Resolving ftp.bit.nl... 213.136.12.213, 2001:7b8:3:37:20e:cff:fe4d:69ac
Connecting to ftp.bit.nl|213.136.12.213|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1474560 (1.4M) [text/plain]
Saving to: `/dev/null'

100%[==============================================================>] 1,474,560    481K/s   in 3.0s

2010-10-11 18:56:03 (481 KB/s) - `/dev/null' saved [1474560/1474560]

--2010-10-11 18:56:03--  http://ftp.bit.nl/pub/OpenBSD/4.7/i386/floppyB47.fs
Reusing existing connection to ftp.bit.nl:80.
HTTP request sent, awaiting response... 200 OK
Length: 1474560 (1.4M) [text/plain]
Saving to: `/dev/null'

100%[==============================================================>] 1,474,560    499K/s   in 2.9s

2010-10-11 18:56:06 (499 KB/s) - `/dev/null' saved [1474560/1474560]

FINISHED --2010-10-11 18:56:06--
Downloaded: 2 files, 2.8M in 5.9s (490 KB/s)

我需要grep总下载速度,也就是字符串490 KB/s

我该怎么做?

备注:可能需要考虑我们只会下载一个文件的情况,因此最终输出不会以FINISHED开头。


wget 'https://x.com' -O /dev/null 2>&1 | grep -oP '(?<= \()\d+\.?\d+ \SB/s(?=\) )' 的解释:将结果保存到 null,将错误重定向到输出,只输出匹配的部分,使用强大的正则表达式,使用正向后行断言和正向前瞻。 - Ray Foss
6个回答

4

使用sed的grep风格版本更新:

wget ... 2>&1 | sed -n '$,$s/.*(\(.*\)).*/\1/p'

旧版本:

我认为,在下载后将文件大小除以下载时间会更容易。 ;-)

新版本:

我认为,下载后将文件大小除以下载时间可以更轻松地计算下载速度。;-)

(/usr/bin/time -p wget ... 2>&1 >/dev/null; ls -l newfile) | \
awk '
   NR==1 {t=$2};
   NR==4 {printf("rate=%f bytes/second\n", $5/t)}
'

第一条awk命令将“real xx.xx”的经过时间存储在变量t中。第二条awk命令将文件大小(通过ls -l命令的第5列)除以时间,将其作为速率输出。


对我来说并不容易。我必须确定文件大小和下载时间,进行除法运算,如果时间等于零怎么办?请提供如何使用bash的示例。 - Nickolai Leschov
报告的时间零需要特别注意。似乎使用grep可能更容易。不知何故,我想到了wget的动态和渐进式输出,我认为很难用grep处理。 - Peter G.

2

对我来说有效的方法是使用您的wget -O /dev/null <resource>

我使用的正则表达式是\([0-9.]\+ [KM]B/s\)

但请注意,我必须将stderr重定向到stdout,因此命令如下:

wget -O /dev/null http://example.com/index.html 2>&1 | grep '\([0-9.]\+ [KM]B/s\)'

这使得像 923 KB/s1.4 MB/s 这样的内容成为可能。


grep 只能找到匹配项。如果要获取值,可以使用 sed

wget -O /dev/null http://example.com/index.html 2>&1 |
    sed -e 's|^.*(\([0-9.]\+ [KM]B/s\)).*$|\1|'

对我来说,它返回包含速度的整行。但是我如何只获取括号内的内容?例如 923 KB/s1.4 MB/s - Nickolai Leschov
现在,使用 sed 的示例确实有效 - 它提取了速度(923 KB/s),但在此之前它也打印出了所有其他输出。 - Nickolai Leschov
@Nick:将它们组合起来。Unix shell 的核心在于管道 - wget abc | grep ghi | sed xyz - Stephen P
2
@NickolaiLeschov,你可以在grep命令中使用--only-matching-o)选项来获取括号内的字符串。 - pix
我相信这种疯狂是有原因的。为什么要用stderr?唉,算了。 - Ray Foss

2

当只下载一个文件时,此方法有效。

我开始使用sed从wget中获取速度,但我发现它很烦人,所以我改用grep。

这是我的命令:

wget ... 2>&1 | grep -o "[0-9.]\+ [KM]*B/s"
-o选项表示只返回匹配的部分。它匹配10个数字中的一个或多个,然后是一个空格。然后是可选的KM,最后是B/s

例如,将返回423 KB/s

要仅匹配单位,请使用grep -o"[KM]*B/s",要仅匹配数字,请使用grep -o"[0123456789]\+


我会从第二个字符类中移除星号,您只需要精确匹配一个K或M。同时请注意输出中有几个速度出现,不是所有速度都对OP有兴趣;完整的解决方案需要考虑上下文,这似乎无法通过单个grep调用完成。 - cmaster - reinstate monica
那只给了我一个输出... :/ 他有多个,但他说他不会有2个文件...?我只使用了1个文件。 - Tim

0
例如,获取以MBit每秒为单位的速度(通过为wget添加--report-speed=bits,并进行小的grep模式更改):
wget -O /dev/null --report-speed=bits http://www.ovh.net/files/10Mb.dat 2>&1 | grep -o "[0-9.,]\+ [KM]*[Bb]/s"

答案:

1,51 Mb/s

这可能无法覆盖以 Gbps 为单位的速度。请增加覆盖范围。 - dm90

-1
为什么你不能就这样做:
perl -ne "/^Downloaded.*?\((.*?)\)/; print $1"

如果只获取了一个文件,则可能没有带有“已下载”字样的那一行。 - Stephen P
2
我该如何与wget一起使用这个东西? - Nickolai Leschov

-3
这里有一个建议。你可以利用 wget--limit-rate=amount 选项。例如, --limit-rate=400k 将限制检索速率为 400KB/s。这样更容易计算总速度。节省你的时间和精力,避免尝试使用正则表达式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接