如何下载 csv 中的 URL 并根据列值命名输出
Posted
技术标签:
【中文标题】如何下载 csv 中的 URL 并根据列值命名输出【英文标题】:How to download URLs in a csv and naming outputs based on a column value 【发布时间】:2019-07-13 19:04:12 【问题描述】:1。操作系统:Linux / Ubuntu x86/x64
2。任务:
编写一个 Bash shell 脚本以下载(大)csv 中的 URL(尽可能快/同时)并在列值上命名每个输出。
2.1 示例输入:
一个包含如下行的 CSV 文件:
001,http://farm6.staticflickr.com/5342/a.jpg
002,http://farm8.staticflickr.com/7413/b.jpg
003,http://farm4.staticflickr.com/3742/c.jpg
2.2 示例输出:
文件夹中的文件,outputs
,包含以下文件:
001.jpg
002.jpg
003.jpg
3。我的尝试:
我主要尝试了两种风格。
1。使用下载工具的内部支持
以ariasc
为例,它支持使用-i
选项导入要下载的URL 文件,并且(我认为)它会以最大速度并行处理它。它确实有--force-sequential
选项来强制按行顺序下载,但我没能找到一种方法来实现命名部分。
2。先拆分
将文件拆分成文件并运行如下脚本来处理它:
#!/bin/bash
INPUT=$1
while IFS=, read serino url
do
aria2c -c "$url" --dir=outputs --out="$serino.jpg"
done < "$INPUT"
但是,这意味着对于每一行,它将再次重新启动aria2c
,这似乎既费时又降低了速度。
虽然,可以多次在 bash 命令中运行脚本以获得“shell 级”并行性,但这似乎不是最好的方法。
有什么建议吗? 谢谢,
【问题讨论】:
参考:CURL 应该可以帮助你.. ***.com/questions/16362402/… 另见Can aria2c download list of urls with specific file names for each。 【参考方案1】:aria2c
在输入文件中支持所谓的选项行。来自man aria2c
-i, --input-file= 下载 FILE 中列出的 URI。您可以通过将多个 URI 放在由 TAB 字符分隔的单行上来为单个实体指定多个源。此外,可以在每个 URI 行之后指定选项。选项行必须以一个或多个空格字符(SPACE 或 TAB)开头,并且每行只能包含一个选项。
以后
这些选项与命令行选项中的含义完全相同,但它只适用于它所属的 URI。请注意,对于输入文件中的选项 -- 前缀必须被去除。
您可以将您的 csv 文件转换为 aria2c
输入文件:
sed -E 's/([^,]*),(.*)/\2\n out=\1/' file.csv | aria2c -i -
这会将您的文件转换为以下格式并在其上运行aria2c
。
http://farm6.staticflickr.com/5342/a.jpg
out=001
http://farm8.staticflickr.com/7413/b.jpg
out=002
http://farm4.staticflickr.com/3742/c.jpg
out=003
但是,这不会创建文件001.jpg
、002.jpg
,...而是001
、002
,...因为这是您指定的。指定带有扩展名的文件名或从 URL 中猜测扩展名。
如果扩展名总是 jpg 你可以使用
sed -E 's/([^,]*),(.*)/\2\n out=\1.jpg/' file.csv | aria2c -i -
要从 URL 中提取扩展名,请使用
sed -E 's/([^,]*),(.*)(\..*)/\2\3\n out=\1\3/' file.csv | aria2c -i -
警告:当且仅当每个 URL 都以扩展名结尾时才有效。例如,由于缺少扩展,001,domain.tld/abc
行根本不会被转换,导致aria2c
在“URL”001,domain.tld/abc
上失败。
【讨论】:
考虑到实际下载速度,选择这个作为ans。图片的实际数量是 960k,所以当我直接放入包含 URL 的文件时,aria2c 会崩溃。可以使用名为split
的bash 命令将文件按行拆分为小文件。 split -l/5 $FILE
,例如。然后一一处理。
你拯救了我的一天。【参考方案2】:
使用所有标准实用程序,您可以并行下载:
tr '\n' ',' < file.csv |
xargs -P 0 -d , -n 2 bash -c 'curl -s "$2" -o "$1.jpg"' -
xargs
中的-P 0
选项允许它并行运行命令(每个核心处理器一个)
【讨论】:
如果 CSV 很大,您希望限制并行任务的数量。如果您同时运行几十个以上,您只会拥塞您的网络。 我认为-P 0
控制它。 ^t 在man xargs
中说If max-procs is 0, xargs will run as many processes as possible at a time
这是 CPU 允许的数量,但它很容易启动,超出您的网络对 I/O 绑定任务的处理能力。
我一直使用 xargs -P 0
对包含 400k-500k 记录的输入文件运行 curl
命令,从未遇到任何阻塞问题。
关系有些复杂。 500 次使用快速网络获取少量连接良好的站点就可以了; 500 次使用快速 CPU 对大量连接性较差的小型站点进行 fetch 会导致您的网络拥塞。以上是关于如何下载 csv 中的 URL 并根据列值命名输出的主要内容,如果未能解决你的问题,请参考以下文章