bash脚本中的并行WGET下载

bash脚本中的并行WGET下载,bash,wget,Bash,Wget,我有一个小脚本,可以从文件中的给定列表下载图像 FILE=./img-url.txt while read line; do url=$line wget -N -P /images/ $url wget -N -P /images/ ${url%.jpg}_{001..005}.jpg done < $FILE FILE=。/img-url.txt 读行时;做 url=$line wget-N-P/images/$url wget-N-P/images/${url%.jpg}{001

我有一个小脚本,可以从文件中的给定列表下载图像

FILE=./img-url.txt
while read line; do
url=$line
wget -N -P /images/ $url
wget -N  -P /images/ ${url%.jpg}_{001..005}.jpg
done < $FILE
FILE=。/img-url.txt
读行时;做
url=$line
wget-N-P/images/$url
wget-N-P/images/${url%.jpg}{001..005}.jpg
完成<$FILE

问题是,它运行太长(文件中的行数超过5000行)。有没有办法加快速度?例如,将源txt拆分为单独的文件并同时运行多个wget实例。

有多种方法可以实现这一点。GNU Parallel将是最通用的解决方案,但是考虑到您提出问题的方式,是的,将文件拆分为多个部分,并在每个部分上同时运行脚本。将文件分成多少部分是一个有趣的问题。100件意味着同时产生100个wget进程。几乎所有这些都将处于空闲状态,而极少数人将利用所有网络带宽。据我所知,一个进程可能会在一个小时内利用所有带宽,但我想一个好的折衷办法是将文件拆分为四个文件,这样4个wget进程可以同时运行。我将调用您的脚本getURL.sh。在命令行中键入此命令

split -l 4 img-url.txt
for f in xaa xab xac xad; do
    ./geturls.sh $f &
done
这会将您的文件拆分为四个~偶数块。默认情况下,split命令输出文件会有一些平淡无奇的文件名,在本例中是xaa、xab等。for循环将这些文件的名称作为命令行参数提供给geturl.sh,这是命令行中程序名之后的第一个参数。将geturls.sh放在后台(&),以便循环的下一次迭代可以立即进行。通过这种方式,geturls.sh几乎同时在文件的所有四个部分上运行,因此您有4个wget进程同时运行

getURL.sh的内容是

#!/bin/bash
FILE=$1
while read line; do
url=$line
wget -N -P /images/ $url
wget -N  -P /images/ ${url%.jpg}_{001..005}.jpg
done < $FILE
#/bin/bash
文件=$1
读行时;做
url=$line
wget-N-P/images/$url
wget-N-P/images/${url%.jpg}{001..005}.jpg
完成<$FILE

我对代码所做的唯一更改是shell的显式声明(大部分是出于习惯),并且该文件现在在$1变量中被赋值。回想一下,$1是(第一个)命令行参数,这里是img-url.txt文件的一个部分的名称。

有很多方法可以做到这一点。GNU Parallel将是最通用的解决方案,但是考虑到您提出问题的方式,是的,将文件拆分为多个部分,并在每个部分上同时运行脚本。将文件分成多少部分是一个有趣的问题。100件意味着同时产生100个wget进程。几乎所有这些都将处于空闲状态,而极少数人将利用所有网络带宽。据我所知,一个进程可能会在一个小时内利用所有带宽,但我想一个好的折衷办法是将文件拆分为四个文件,这样4个wget进程可以同时运行。我将调用您的脚本getURL.sh。在命令行中键入此命令

split -l 4 img-url.txt
for f in xaa xab xac xad; do
    ./geturls.sh $f &
done
这会将您的文件拆分为四个~偶数块。默认情况下,split命令输出文件会有一些平淡无奇的文件名,在本例中是xaa、xab等。for循环将这些文件的名称作为命令行参数提供给geturl.sh,这是命令行中程序名之后的第一个参数。将geturls.sh放在后台(&),以便循环的下一次迭代可以立即进行。通过这种方式,geturls.sh几乎同时在文件的所有四个部分上运行,因此您有4个wget进程同时运行

getURL.sh的内容是

#!/bin/bash
FILE=$1
while read line; do
url=$line
wget -N -P /images/ $url
wget -N  -P /images/ ${url%.jpg}_{001..005}.jpg
done < $FILE
#/bin/bash
文件=$1
读行时;做
url=$line
wget-N-P/images/$url
wget-N-P/images/${url%.jpg}{001..005}.jpg
完成<$FILE

我对代码所做的唯一更改是shell的显式声明(大部分是出于习惯),并且该文件现在在$1变量中被赋值。回想一下,$1是(第一个)命令行参数,这里是img-url.txt文件的一个部分的名称。

Relevant:Relevant:Perfect,但是-l开关应该是代码中的-n开关。我无法编辑代码中的一个字符。还有一个问题:脚本不会在结尾退出。我应该将“退出0”命令放在哪里?我以前试过(两个都试过),但都没用。看起来-n和-l会做同样的事情,但我相信你的话。:)“退出0”命令是多余的。如果脚本到达底部,默认假设它正确完成。但如果存在非零退出状态,您可能想知道。所以设置出口0。。。我想不出一个好理由。我的意思是,如果有问题,那么设置出口0将掩盖这一点。如果可能,您总是希望退出状态传递一些有用的信息。这并不总是容易的。但每次将其设置为单个值都会消除这种可能性。我无法编辑代码中的一个字符。还有一个问题:脚本不会在结尾退出。我应该将“退出0”命令放在哪里?我以前试过(两个都试过),但都没用。看起来-n和-l会做同样的事情,但我相信你的话。:)“退出0”命令是多余的。如果脚本到达底部,默认假设它正确完成。但如果存在非零退出状态,您可能想知道。所以设置出口0。。。我想不出一个好理由。我的意思是,如果有问题,那么设置出口0将掩盖这一点。如果可能,您总是希望退出状态传递一些有用的信息。这并不总是容易的。但每次将其设置为单个值都会消除这种可能性。