如果文件具有相同的基本名称,我希望 wget 优先选择某种文件类型。
例如:
如果foo.ogg可用,请勿下载foo.mp3
我目前使用 wget 抓取/自动下载的方式(如果有人感兴趣的话):
wget -Dfoo.com -I /folder/ -r -l 1 -nc -A.ogg,.mp3 http://www.foo.com/folder/
但当然,获取 .mp3 和 .ogg文件。有什么想法吗?
- (语法说明:-D
:仅从此域下载
-I:仅从此域的子文件夹下载
-r:递归(跟踪链接和目录结构)
-l 1:仅跟踪 1 个深层链接
-nc:无 clobber = 仅当文件不存在时下载
-A:仅接受/下载所有 *.ogg 和 *.mp3(丢弃必要的 html 文件)
(-i(可选地放在 URL 前面):从 URL 读取 URL,但也下载其他文件类型,例如 .png(您一开始并不想要这些文件类型/之后丢弃它们)
答案1
单个文件
为了实现“如果文件X存在则下载;否则下载文件是",您可以进行如下操作:
wget x || wget y
如果X存在,则下载并wget
返回true
,因此跳过第二部分。如果X不存在,wget
则返回一些错误代码(可能是 8),然后计算表达式的第二部分(下载是)。
递归地
不过,这显然对你的递归下载没有多大帮助。如果wget
有设施可以容纳这种复杂程度的屏蔽,我会感到惊讶。手册页似乎也没有涵盖任何形式的花哨条件。不过,稍微修改一下方法就可以了。
(似乎很难说服wget
它制作一份要下载的内容的列表。我的第一个想法是创建这个列表并在下载之前对其进行适当的过滤,就像@utkuerd 建议的那样。)
首先当然是下载所有的 ogg 文件,大概是
wget -Dfoo.com -I /folder/ -r -l 1 -nc -A.ogg -i http://www.foo.com/folder/
然后,可以用相同的方法下载剩余的 mp3 文件,前提是您有合适的掩码作为列表提供--reject
。此列表应包含您不想下载的每个 mp3 文件的名称。
假设我建议你按如下方式创建此列表
bl=($(find ./ -name '*.ogg' -exec basename -s .ogg {} \+ | sed 's/\(^.\+$\)/\1.mp3/' ) )
您现在有一个要阻止的 mp3 文件的 bash 数组。
要仅下载未阻止的 mp3 文件,您可以使用
IFS=','; wget -Dfoo.com -I /folder/ -r -l 1 -nc -A.mp3 -R"${bl[*]}" -i http://www.foo.com/folder/; unset IFS
必须修改变量IFS
以便列表不被空格分隔。
显然,如果 ogg 文件列表超过getconf ARG_MAX
(这将破坏 wget 命令)或文件名包含空格(这将破坏阻止列表,可能会给您一个额外的文件和(不太可能)丢失的文件),这种情况会在不同程度上恶化。两者都是可以修复的。
请注意,拒绝列表中多余的逗号会导致有趣的结果。
写下@Bob 的优秀建议
(见下文评论)
获取ogg文件后
wget -Dfoo.com -I /folder/ -r -l 1 -nc -A.ogg -i http://www.foo.com/folder/
你可以像这样创建虚拟 mp3 文件
find ./ -name '*.ogg' | sed 's/ogg$/mp3/' | xargs -d '\n' touch
并获取剩余的 mp3 文件(利用-nc
)
wget -Dfoo.com -I /folder/ -r -l 1 -nc -A.mp3 -i http://www.foo.com/folder/
然后可以使用类似以下命令删除多余的 mp3 文件
find ./ -name '*.mp3' -size 0 -exec rm '{}' \+
我测试过这是否适用于名称中的空格。
答案2
我不认为 wget 的 -A 选项能够以智能方式在给定的文件名模式中进行选择。很可能您需要一个脚本来实现您想要的功能。您应该获取目录列表,自己解析它,然后下载您想要的文件。
对于正在下载和丢弃的 .png 文件,您错误地使用了 -i 标志。-i 标志指定包含要下载的 URL 的文件(或 URL)。您应该指定起始点而不使用任何标志。如果您删除 -i 标志,则不会下载其他文件类型,而只会下载 .ogg、.mp3 和必要的 html 文件。之后 html 文件将被丢弃。