![wget - 如何使用自定义文件夹结构从 CSV 下载文件列表](https://linux22.com/image/214690/wget%20-%20%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E8%87%AA%E5%AE%9A%E4%B9%89%E6%96%87%E4%BB%B6%E5%A4%B9%E7%BB%93%E6%9E%84%E4%BB%8E%20CSV%20%E4%B8%8B%E8%BD%BD%E6%96%87%E4%BB%B6%E5%88%97%E8%A1%A8.png)
我有一个 CSV,包含 2 列、ID 和由 分隔的图像 url 列表|
,文件数量是可变的,例如:
ID_0;https://via.placeholder.com/350x150.jpg|https://via.placeholder.com/250x150.jpg
ID_1;https://via.placeholder.com/350x150.jpg|https://via.placeholder.com/250x150.jpg
ID_2;https://via.placeholder.com/450x150.jpg
有没有办法wget
下载以 ID 值命名的文件夹中的所有图像?
编辑:
这是我到目前为止所尝试过的:
#!/bin/bash
while IFS=';' read -r product_code img
do
wget $img -P $product_code
done < test.csv
答案1
一种简单的方法:
#!/bin/bash
while read -r id urls; do
( mkdir -p "$id" && cd "$id" && wget $urls )
done < <(sed 's/[|;]/ /g' file)
输出
ls ID_*
ID_0:
250x150.jpg 350x150.jpg
ID_1:
250x150.jpg 350x150.jpg
答案2
这是我想出的解决方案:
#!/bin/bash
while IFS=';' read -r product_code image_list # Parse each line of the CSV and assing its ; separated values
do
img_array=( $(echo "$image_list" | tr "|" "\n") ) # Create an Array of urls starting from a | separated string
for image in "${img_array[@]}" # Parse each element of the Array
do
wget "$image" -P "$product_code" # Download Image in specific folder
done
done < test.csv
关于输入文件,这些是条件:
- 第一列
product_code
是一个字符串,可以包含A-z
、0-9
、_
和空格; - 第二列
image_list
是由字符分隔的 url 列表|
,长度可变,每个文件名可以包含A-z
,0-9
,_
;
答案3
tr ';|' '\t\t' <file | xargs -L 1 sh -c 'dir=$1; shift; wget -q -P "$dir" "$@"' sh
这假定 ID 和 URL 不包含字符;
或|
或任何空白字符。它用制表符替换每个;
and字符,然后使用输入的每一行(在制表符上分解为单独的字符串)作为参数重复调用一个简短的内联 shell 脚本。|
xargs
简短的内联 shell 脚本将第一个命令行参数 ID 转移到变量中dir
,然后wget
将此作为-P
选项 ( --directory-prefix
) 的参数进行调用,并将其余参数作为 URL 操作数进行调用。
测试:
$ tree
.
`-- file
0 directories, 1 file
$ tr ';|' '\t\t' <file | xargs -L 1 sh -c 'dir=$1; shift; wget -q -P "$dir" "$@"' sh
$ tree
.
|-- ID_0
| |-- 250x150.jpg
| `-- 350x150.jpg
|-- ID_1
| |-- 250x150.jpg
| `-- 350x150.jpg
|-- ID_2
| `-- 450x150.jpg
`-- file
3 directories, 6 files
如果您支持,这可以使用(某个数字,例如 4)与xargs
并行运行。-P n
n
xargs
如果你懒的话,你可以将上面的内容简化为
tr ';|' '\t\t' <file | xargs -L 1 sh -c 'wget -q -P "$0" "$@"'
...我们滥用这样一个事实,即 的第一个操作数sh -c
存储在 中$0
,并且这不是位置参数列表的一部分,"$@"
。但是,习惯上将脚本或 shell 的名称放入其中(这就是分隔符上方代码中的$0
尾随名称)。 sh
shell 将$0
在其诊断消息中使用。
答案4
如果您有 GNU Parallel:
cat file |
parallel --colsep '[|;]' 'mkdir -p {1} && cd {1} && wget {=1 $arg[1]=""; $_="@arg"; uq(); =}'
Explanation:
$arg[1]="" -- remove first argument
$_="@arg" -- join arguments with " "
uq() -- do not quote the result
或者:
cat file |
parallel --colsep ';' 'mkdir -p {1} && cd {1} && wget {=2 s/\|/ /g; uq(); =}'
Explanation:
2 s/\|/ /g -- replace | with " " in argument 2
这对于并行下载更多 URL 可能会很方便。