json
URLに保存されているファイルからURLをダウンロードする必要がありますcsv
。これは手動で実行できないため、Pythonを使用してURLを1つずつ読み、curl
ダウンロードに渡す短いbashスクリプトを作成しました。また、tee
スクリプトは、その助けを借りてダウンロードしたデータをファイルに保存し、標準コードを使用して各ファイルの名前を指定します。コードは同じフォルダに保存され、csv
ファイルは「Data」という別のフォルダに保存されます。
output_dir=Data
python pass_urls_to_std_out.py | xargs curl -k | tee $output_dir/$(python pass_cd_to_std_out.py) > /dev/null
pass_urls_to_std_out.py
URLを読み込み、1つずつ標準出力に渡す短いPythonスクリプトです。
pass_cd_to_std_out.py
コードを1つずつ読み込む同様のスクリプトです。
> /dev/null
tee
画面にすべての出力が印刷されるのを防ぐために使用されます。curl
残念ながら、このスクリプトは小さなファイルセットでうまく機能しますが、ダウンロードするファイルの数が増えると、次のエラーメッセージが表示されます。
tee: 4208005.json: Too many open files
tee: 4110607.json: Too many open files
tee: 4304903.json: Too many open files
tee: 4217303.json: Too many open files
tee: 4212809.json: Too many open files
tee: 4214003.json: Too many open files
tee: 4208302.json: Too many open files
tee: 4203501.json: Too many open files
....
一度にファイルをすべて開かずに、出力を一度に1つのファイル(または一度に10、20ファイル)に順次リダイレクトする方法はありますか?
[編集]カミール・マコロフスキー私が書いて正確に指摘したように、pass_cd_to_std_out.py
出力は1つずつ引数として渡されるのではなく、拡張され、一度tee
に複数の引数に渡されます。
スクリプトをforループに書き直しました。
#!/bin/bash
output_dir=Data
for url in $(eval python pass_urls_to_std_out.py); do
curl -k $url > $output_dir/$(python pass_cd_to_std_out.py)
done
残念ながら、これは$output_dir
一度だけ評価されるので、出力は次のようになります。
Data/1200401.json
4205407.json
4106902.json
2304400.json
3304557.json
3205309.json
1600303.json
1400100.json
答え1
すべてをすぐにパイプするのではなく、各ステップをファイルに保存すると何らかの方法で動作することがわかりました。
- ディレクトリが
Data
あることを確認し、そうでない場合はディレクトリを作成しますData
。download_dir=Data if [ ! -d $download_dir ]; then mkdir $download_dir fi
- すべてのURLを含むファイルを作成します。
python pass_urls_to_std_out.py >> urls.txt
- すべてのファイル名を含むファイルを作成します。
python pass_cd_to_std_out.py >> file_names.txt
- 各ファイルを1行ずつ読み、URLからデータを再帰的にダウンロードし、ファイル名に保存します。
paste urls.txt file_names.txt | while IFS= read -r url file_name; do curl -k --output-dir=Data $url > $file_name; done