如何使wget重命名下载的文件以不包含查询字符串?


32

我正在下载一个带有wget的网站,并且许多链接都附加了查询,因此,当我这样做时:

wget -nv -c -r -H -A mp3 -nd http://url.to.old.podcasts.com/

我最终得到了很多这样的文件:

1.mp3?foo=bar
2.mp3?blatz=pow
3.mp3?fizz=buzz

我想结束的是:

1.mp3
2.mp3
3.mp3

这都是在ubuntu linux中进行的,我有wget 1.10.2。

我知道我可以通过脚本获得所有内容以重命名所有内容后执行此操作。但是我真的很想从wget中获取解决方案,以便在下载过程中可以看到正确的名称。

谁能帮我解决这个问题?


在www.stackoverflow.com上发布您的问题。
Deniz Zoeteman

3
@TutorialPoint为什么?问题是寻找一种内部的方法,因此将其迁移回这里。
奎克吉x德09年

好吧,没有内在的方法可以做
ayrnieu

1
@ayrnieu:不是一个命令,没有。并非没有助手。但您当然可以用最少的n + 1个wget命令(如果不是更少的话)来完成。
09年

Answers:


24

如果服务器是同类服务器,则它可能会在下载内容中粘贴Content-Disposition标头,以告知客户端正确的文件名。告诉wget监听标头中的最终文件名很简单:

wget --content-disposition

您需要wget的最新版本才能使用此功能。

我不知道它如何处理声称文件名为“ / etc / passwd”的服务器。


我对此问题没有任何疑问,因为它无疑适用于某些情况。不幸的是,对于某些在其中包含类型版本控制的, Cloudfront服务的页面,它对我不起作用?v=blah。我不知道,可能有一些特定于Cloudfront的方式来请求文档,而没有这些方式,但是我没有找到一种方式,因此在这种情况下,很可能需要其他答案之一。(如果有人知道剥离v=字符串或让Cloudfront不提供字符串的方法,我很想听听。)
lindes

17

在处理了一大批之后,我意识到我应该指示wget忽略查询字符串。我不想再做一次,所以我制作了一个对我有用的脚本:

# /bin/bash
for i in `find $1 -type f`
do
    mv $i `echo $i | cut -d? -f1`
done

把那像一个文件rmqstrchmod +x rmqstr 语法:./rmqstr <directory (defaults to .)>

它将从所有文件名中递归删除查询字符串。


2
我会添加`-name“ \? ”`来查找仅限于所需文件的部分:)
Arkadiusz“飞翔” Rzadkowolski

4

我认为,为了wget保存为不同于URL指定的文件名,您需要使用-O filename参数。仅当您给它提供一个URL时,它才可以满足您的要求-具有多个URL,所有下载的内容都以结尾filename

但这确实是答案。与其尝试在一个wget命令中完成所有操作,不如使用多个命令。现在您的工作流程变为:

  1. 运行wget以获取包含您的链接的基本HTML文件;
  2. 解析URL;
  3. 以结尾的Foreach网址mp3
    1. 过程网址获得的文件名(如转http://foo/bar/baz.mp3?gargle=blasterbaz.mp3
    2. (可选)检查文件名是否不存在
    3. wget <URL> -O <filename>

这就解决了您的问题,但是现在您需要弄清楚如何获取基本文件以找到您的mp3URL。

您是否有特定的网站/基本URL?通过一个具体示例,将更易于处理步骤1和3。


1

这样我就可以在下载过程中看到正确的名称。

好。像平常一样使用wget;使用您通常使用的post-wget脚本,但是要处理wget的输出,以便于使用:

#! /bin/sh
exec wget --progress=bar:force $* 2>&1 | \
  perl -pe 'BEGIN { $| = 1 } s,(?<=`)([^\x27?]+),\e[36;1m$1\e[0m, if /^Saving/'
cgi-cut # rename files

这仍然会显示?foo=bar你下载了,但会在明亮的蓝绿色显示的姓名的其余部分。


这在某种程度上解决了显示文件名的问题,但是OP也希望最终文件名不包含查询字符串。
Michael Mior 2014年

1

我有与@Gregory Wolf类似的方法,因为他的代码始终会创建如下错误消息:

mv:“ ./ file”和“ ./file”是同一文件

因此,在移动文件之前,我首先检查文件名中是否有查询字符串:

for f in $(find $1 -type f); do
    if [ $f = ${f%%\?*} ]; then continue; fi
    mv "${f}" "${f%%\?*}"
done

这将递归检查每个文件,并删除文件名中的所有查询字符串(如果有)。


0

查看我创建的用于克隆站点的这两个命令,克隆完成后,您可以执行第二个命令。

第二个命令将查看整个克隆,搜索“ ”文件模式名称,并从文件名中删除查询字符串。

# Clone entire site.
    wget --content-disposition --execute robots=off --recursive --no-parent --continue --no-clobber http://example.com

# Remove query string from a static resource.
for i in `find $1 -type f -name "*\?*"`; do mv $i `echo $i | cut -d? -f1`; done

(在GitHub Gist中查看。)


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.