![如何将多行列表中的 wget 转换为一个文件名?](https://linux22.com/image/130791/%E5%A6%82%E4%BD%95%E5%B0%86%E5%A4%9A%E8%A1%8C%E5%88%97%E8%A1%A8%E4%B8%AD%E7%9A%84%20wget%20%E8%BD%AC%E6%8D%A2%E4%B8%BA%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%E5%90%8D%EF%BC%9F.png)
我想获取从 XML 文件中检索的项目列表。我使用 sed 来清理 XML,最终得到如下输出:
CountofMonteCristo.zip
English.
http://www.archive.org/download/count_monte_cristo_0711_librivox/count_monte_cristo_0711_librivox_64kb_mp3.zip
Alexandre.
Dumas.
LettersofTwoBrides.zip
English.
http://www.archive.org/download/letters_brides_0709_librivox/letters_brides_0709_librivox_64kb_mp3.zip
Honoréde.
Balzac.
BleakHouse.zip
English.
http://www.archive.org/download/bleak_house_cl_librivox/bleak_house_cl_librivox_64kb_mp3.zip
Charles.
Dickens.
我想使用 wget -i 将这些文件下载为 Language.Lastname.Firstname.Title.zip
我愿意以某种方式重新排列文件,以便我可以使用 $filename $url
我尝试了一些不同的 sed 命令。我用 Sed 来清理 XML 标签,但我不知道如何将文本移动到适当的位置。每个文件的标题、名称和语言都会有所不同。
编辑:在用 sed 清理标签之前,每一行都用标签包装,例如 English 和 FileTitle。我认为这可能有助于识别重新安排事物的模式。
编辑2:这是XML源
编辑3:一些东西像这样看起来它可以工作,但我在修改它以满足我的需要时遇到了困难。
我的最终目标是将所有文件组织到文件夹中,层次结构为 Language -> AuthorLastnameFirstname -> Files.zip
如果我所做的不是最佳实践,我愿意接受其他方法。
谢谢
答案1
如果我所做的不是最佳实践,我愿意接受其他方法。
我建议你不要使用bash
或sed
等等!并使用 python 方式,这绝对是解析您需要解析的 xml 的更好方法。我刚刚用 python3.6 编写并测试了它,它完全符合您的要求。
#!/usr/bin/python3
# Let's import the modules we need
import wget
import os
import requests
from bs4 import BeautifulSoup as bs
# Assign the url to a variable (not essential as we
# only use it once, but it's pythonic)
url = 'https://librivox.org/api/feed/audiobooks/?offset=0&limit=3&fields=%7Blanguage,authors,title,url_zip_file%7B'
# Use requests to fetch the raw xml
r = requests.get(url)
# Use BeautifulSoup and lxml to parse the raw xml so
# we can do stuff with it
s = bs(r.text, 'lxml')
# We need to find the data we need. This will find it and create some
# python lists for us to loop through later
# Find all xml tags named 'url_zip_file' and assign them to variable
links = s.find_all('url_zip_file')
# Find all xml tags named 'last_name' and assign them to variable
last_names = s.find_all('last_name')
# Find all xml tags named 'last_name' and assign them to variable
first_names = s.find_all('first_name')
# Find all xml tags named 'language' and assign them to variable
language = s.find_all('language')
# Assign the language to a variable
english = language[0].text
# Make our new language directory
os.mkdir(english)
# cd into our new language directory
os.chdir(str(english))
# Loop through the last names (ln), first names(fn) and links
# so we can make the directories, download the file, rename the
# file then we go back a directory and loop again
for ln, fn, link in zip(last_names, first_names, links):
os.mkdir('Author{}{}'.format(str(ln.text), str(fn.text)))
os.chdir('Author{}{}'.format(ln.text, fn.text))
filename = wget.download(link.text)
os.rename(filename, 'File.zip')
os.chdir('../')
您可以将其保存到文件中,也可以将其粘贴/输入到 python3 解释器 cli 中,这取决于您。
您需要安装python3-wget和美丽汤4使用 pip 或 easy_install 等
答案2
如果您可以使用,Librivox API 还提供 JSON 输出,并且使用适当的 XML 工具jq
解析 JSON 可能比解析 XML 更容易。jq
u='https://librivox.org/api/feed/audiobooks/?offset=0&limit=3&fields=%7Blanguage,authors,title,url_zip_file%7B&format=json'
curl "$u" -sL |
jq -r '.books[] | "\(.language).\(.authors[0].last_name + .authors[0].first_name).\(.title).zip", .url_zip_file'
给出如下输出:
English.DumasAlexandre.Count of Monte Cristo.zip
http://www.archive.org/download/count_monte_cristo_0711_librivox/count_monte_cristo_0711_librivox_64kb_mp3.zip
English.BalzacHonoré de.Letters of Two Brides.zip
http://www.archive.org/download/letters_brides_0709_librivox/letters_brides_0709_librivox_64kb_mp3.zip
English.DickensCharles.Bleak House.zip
http://www.archive.org/download/bleak_house_cl_librivox/bleak_house_cl_librivox_64kb_mp3.zip
之后使用起来就比较简单了xargs
:
curl "$u" -sL |
jq -r '.books[] | "\(.language).\(.authors[0].last_name + .authors[0].first_name).\(.title).zip", .url_zip_file' |
xargs -d '\n' -n2 wget -O
其中xargs
使用两行作为参数wget
,第一行成为-O
选项参数,第二行成为 URL。
虽然我会推荐像 Jamie 那样的基于 Python 的解决方案,除了使用 JSON 和 Python 的内置 JSON 功能而不是 bs4。
答案3
蛮力。
如果您解析的 xml 位于books
while read a; read b; read c; read d; read e; do wget $c -O $b$e$d$a; echo $c; done < books
只需将行重新组合为变量即可,只要将记录块填充到 5 行即可。