我需要json
从存储在csv
.由于不可能手动执行此操作,因此我编写了一个简短的 bash 脚本,使用 Python 逐个读取 URL 并将其传递给curl
下载。此外,借助 的帮助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
只是一个简短的 Python 脚本,它读取 url 并将它们一一传递到标准输出。
pass_cd_to_std_out.py
是一个类似的脚本,它只是一个接一个地读取代码。
> /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
....
有没有一种方法可以一次按顺序将输出重定向到一个文件(或一次 10 个、20 个文件),而无需尝试一次打开所有文件?
[编辑] 作为卡米尔·马乔罗夫斯基正如我所写的那样,正确地指出,它不是pass_cd_to_std_out.py
作为 的参数一一传递的输出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
- 逐行读取每个文件并从 url 递归下载数据并保存到文件名:
paste urls.txt file_names.txt | while IFS= read -r url file_name; do curl -k --output-dir=Data $url > $file_name; done