wget:下载文件名

23

我正在编写一个 Bash 脚本,需要使用 wget 获取已下载的文件名并将其放入 $string 中。

例如,如果我下载了下面这个文件,我希望把它的名字,mxKL17DdgUhcr.jpg,放到 $string 中。

wget http://pics.sitename.com/images/191211/mxKL17DdgUhcr.jpg
45439 (44K) [image/jpeg]
Saving to: «mxKL17DdgUhcr.jpg»

100%[===================================================================================================>] 45 439      --.-K/s   в 0s

2011-12-20 12:25:33 (388 MB/s) - «mxKL17DdgUhcr.jpg» saved [45439/45439]

1
可能是使用wget --content-disposition 'url'命令。 - Ferroao
11个回答

51
wget --server-response -q -O - "https://very.long/url/here" 2>&1 | 
  grep "Content-Disposition:" | tail -1 | 
  awk 'match($0, /filename=(.+)/, f){ print f[1] }' )

由于可能存在多个301/302重定向,最后使用Content-Disposition:头设置文件名,因此这是正确的版本。

基于URL猜测文件名并不总是正确的。


2
我喜欢这种方法,但不幸的是,在Debian衍生版(例如Ubuntu)中的awk不支持match函数的第三个参数。 - jtravaglini
虽然不总是完美无缺,但这是正确的方法。 - diedthreetimes
1
在Ubuntu中,你可以使用以下命令:wget --server-response -q -O - "https://very.long/url/here" 2>&1 | grep "Content-Disposition:" | tail -1 | awk -F"filename=" '{print $2}' - Gowtham
10
现代简单的实现方式:wget {link} --content-disposition - balbelias
1
@balbelias:这将正确地使wget使用服务器建议的名称。但是...如何检索它并将其分配给变量? - MestreLion

40

使用basename命令从URL中提取文件名。例如:

url=http://pics.sitename.com/images/191211/mxKL17DdgUhcr.jpg
filename=$(basename "$url")
wget "$url"

16
警告:此方法无法处理包含重定向或动态内容的 URL。请参考est的答案获取正确的解决方案。 - Gowtham
我喜欢它!但是如果有URL参数,它也不会完全起作用。例如https://github.com/awslabs/aws-well-architected-labs/blob/master/Reliability/300_Testing_for_Resiliency_of_EC2_RDS_and_S3/Code/Python/server.py?raw=1 - Seth E

23

您可以在下载之前使用 -O 选项指定文件名,使用 wget 命令:

wget -O myfile.html http://www.example.com/

4
虽然不像其他答案那么“聪明”,但这种方法实际上具有简单和可预测性的优势。 - Seth E

3

PizzaBeer提到的那样,wget会告诉你文件保存在哪里。这很重要,因为它将确保不覆盖现有文件,而是在文件名末尾添加一个数字

因此,这是我的解决方案,使用grep缩小好的行范围(由于wget的工作方式,需要使用--line-buffered,请参见这里),并使用sed提取文件名。

wget --content-disposition $1 2>&1 | grep "Saving to" --line-buffered | sed -r 's/Saving to: ‘(.*)’/\1/'

你可以将这个存储在一个变量中,在下载结束时会填充该变量。

3
您可以这样明确指定名称:

url='http://pics.sitename.com/images/191211/mxKL17DdgUhcr.jpg'
file=`basename "$url"`
wget "$url" -O "$file"

2
处理URL编码的文件名:
URL="http://www.example.com/ESTAD%C3%8DSTICA(2012).pdf"
BASE=$(basename ${URL})             # ESTAD%C3%8DSTICA(2012).pdf
FILE=$(printf '%b' ${BASE//%/\\x})  # ESTADÍSTICA(2012).pdf
wget ${URL}

2
#!/bin/bash
file=$(wget $1 2>&1 | grep Saving | cut -d ' ' -f 3 | sed -e 's/[^A-Za-z0-9._-]//g')

我喜欢这个命令,因为wget 告诉你它正在保存的文件名。使用sed可以去除非文件名字符,例如撇号。


1

除了 @Gowtham Gopalakrishnan 的答案,另一种方法是:

wget --server-response -q "https://very.long/url/here" 2>&1 | awk -F"filename=" '{if ($2) print $2}'

这只输出在内容中设置的文件名。

示例

$ wget --server-response -q https://hostname/filename-that-i-liek.zip 2>&1 | awk -F"filename=" '{if ($2) print $2}'
"filename-that-i-liek.zip"

1
~ $ URL='http://pics.sitename.com/images/191211/mxKL17DdgUhcr.jpg'
~ $ echo ${URL##*/}
mxKL17DdgUhcr.jpg
~ $ wget $URL -O ${URL##*/}
--18:34:26--  http://pics.sitename.com/images/191211/mxKL17DdgUhcr.jpg
           => `mxKL17DdgUhcr.jpg'

0

我猜您已经在某个变量中拥有文件的完整URL。使用Bash参数扩展来去掉前缀:

echo ${url##*/}

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