wget - 如何使用自定义文件夹结构从 CSV 下载文件列表

wget - 如何使用自定义文件夹结构从 CSV 下载文件列表

我有一个 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-z0-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 nnxargs


如果你懒的话,你可以将上面的内容简化为

tr ';|' '\t\t' <file | xargs -L 1 sh -c 'wget -q -P "$0" "$@"'

...我们滥用这样一个事实,即 的第一个操作数sh -c存储在 中$0,并且这不是位置参数列表的一部分,"$@"。但是,习惯上将脚本或 shell 的名称放入其中(这就是分隔符上方代码中的$0尾随名称)。 shshell 将$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 可能会很方便。

相关内容