如何将多行列表中的 wget 转换为一个文件名?

如何将多行列表中的 wget 转换为一个文件名?

我想获取从 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

如果我所做的不是最佳实践,我愿意接受其他方法。

我建议你不要使用bashsed等等!并使用 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 行即可。

相关内容