我想每天下载一个播客。它采用mp3文件的形式,因此目标文件的扩展名始终相同。文件名的第一部分也不会改变——我们称之为ProgName-。文件名的另一段以可预测的方式更改;这是今天的日期,格式是1999年1月1日。但文件名的中间部分以相当不可预测的方式变化:它由8个明显随机的整数组成。文件名的结尾,即扩展名之前的部分,也不会改变——假设它是"-完整的"。因此,1999年1月1日的示例文件名如下:ProgName-01-01-1999-01238764-full.mp3。第二天(1月2日)的文件名为ProgName-01-02-1999-23871640-full.mp3。等等
这些文件是通过http提供的,一旦我通过浏览网页找到完整路径,我就可以使用wget下载它们。但我正在努力实现这一点的自动化,并希望能想出一个cron工作,我可以在每天的某个时间运行,在我确信最新一集会出现的时候。作为的一个例子
wget http://my.desiredurl.here/downloads/ProgName-01-01-1999-01238764-full.mp3
成功地将文件ProgName-01-01-199-01238764-full.mp3下载到我的计算机(非认证网站)。但是,在我能想出一种方法(也许是使用通配符或大括号扩展?)来实现自动化之前,我一直在手动下载。所以我想寻求帮助。
我已经阅读了一些关于支架扩展的文章,但对bash的了解还不够初级,我有点猜测这可能是如何工作的。我可以期待吗
wget http://my.desiredurl.here/downloads/ProgName-01-01-1999-{00000000..99999999}-full.mp3
去上班?这是做这类事情的最佳方式吗?我想我已经弄清楚如何自动输入文件名的日期部分,但目前对整数字符串感到困惑。我们将不胜感激。
附言:在这里发帖之前,我在谷歌上搜索了很多关于这个问题的内容。我遇到的大多数wget解决方案都涉及globbing和递归下载,这确实不是我所需要的。目标站点上有很多.mp3文件,但我只需要其中一个。我需要一种方法来过滤掉除了包含今天日期的目标文件之外的所有文件。curl也在我的机器上,可以用来做这个,尽管我的重点是我更熟悉的wget。
我想我已经找到了这个问题的解决方案。这比我想象的要复杂一些,但到目前为止的测试表明它应该能完成任务。我得到了以下帮助:1)意识到使用curl或wget,我可以下载一个xml文档,其中包含我需要的直接链接;和2)在http://nylinuxhelp.com/blogs/command-line/download-several-files-part-2.
首先,我使用curl获取包含所需URL的xml文件。我将其作为输出输出到grep,告诉它搜索一个以http开头、以mp3结尾的字符串,并在找到第一个结果后结束搜索-m 1,这恰好是我瞄准的最近一集。最后,grep命令的输出通过xargs管道传输到wget,wget下载并重命名文件。完整的一行看起来像这样:
curl http://my.desiredurl.here/level1/level2/ | grep -m 1 -o "http:.*mp3" | xargs -n1 wget -O MyDownloaded.mp3
我需要做进一步的测试,以确保它在设置为cron作业时能够按需工作。我可能可以从这个例程的xargs段中删除-n1,因为我一次只能从xargs向wget提供一个URL。我也应该把它嵌入到一个原始的bash脚本中,因为我想按照上面Charles演示的方式将日期合并到文件名中。
更新版:今晚我进行了一个测试,将这个脚本设置为cron作业,它的表现就像冠军一样。当然,它非常原始,没有错误检查、日志记录或重定向无关输出。因此,它当然需要改进。我的bash"技能",就像它们一样,不允许我做比我已经做的更多的事情,所以我会暂时按原样做。
告诉wget过滤您期望的文件名模式,并将一个URL交给它,您希望从中可以获得下载链接。
这看起来像:
date=$(date +%m-%d-%Y) # aside: Awful date format; %Y-%m-%d is what sane folks use.
expected_name="ProgName-$date-*.mp3"
wget --recursive --level=2 --accept "$expected_name" http://my.desiredurl.here/
注意--level=2
——这限制了递归的深度。修改为相对于所提供的URL所需的最小值(并尝试使该URL尽可能靠近下载链接的位置)。