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コマンドを試しました。 XMLタグを整理するためにSedを使用していますが、テキストを適切な場所に移動する方法がわかりません。各ファイルには異なるタイトル、名前、言語があります。
編集: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そして美しいスープ4pipやeasy_installなどを使用してください。
答え2
Librivox APIは、利用可能な場合はJSON出力も提供し、適切なXMLツールを使用してjq
XMLを解析するよりもJSONを解析する方が簡単です。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
2行はパラメータとして使用されます。wget
最初の行は-O
オプションパラメータ、2行目はURLです。
おすすめしたいけどJamieなどのPythonベースのソリューションただし、bs4の代わりにJSONとPythonの組み込みJSON機能を使用することは除外されます。
答え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行で埋めます。