Adr*_*ian 10 bash wget gnu-parallel
我正在使用此脚本下载文件:
parallel --progress -j16 -a ./temp/img-url.txt 'wget -nc -q -P ./images/ {}; wget -nc -q -P ./images/ {.}_{001..005}.jpg'
Run Code Online (Sandbox Code Playgroud)
是不是可以不下载文件,只是在远程端检查它们,如果存在则创建一个虚拟文件而不是下载?
就像是:
if wget --spider $url 2>/dev/null; then
#touch img.file
fi
Run Code Online (Sandbox Code Playgroud)
应该工作,但我不知道如何将此代码与GNU Parallel结合起来.
编辑:
根据Ole的回答,我写了这段代码:
#!/bin/bash
do_url() {
url="$1"
wget -q -nc --method HEAD "$url" && touch ./images/${url##*/}
#get filename from $url
url2=${url##*/}
wget -q -nc --method HEAD ${url%.jpg}_{001..005}.jpg && touch ./images/${url2%.jpg}_{001..005}.jpg
}
export -f do_url
parallel --progress -a urls.txt do_url {}
Run Code Online (Sandbox Code Playgroud)
它可以工作,但它对某些文件失败了.我无法找到为什么它适用于某些文件的一致性,为什么它对其他文件失败.也许它有最后一个文件名的东西.第二个wget尝试访问当前url,但之后的touch命令根本不会创建desidered文件.第一个wget总是(正确地)下载没有_001.jpg,_002.jpg的主图像.
示例urls.txt:
http://host.com/092401.jpg(工作正常,_001.jpg .._ 005.jpg下载) http://host.com/HT11019.jpg(不起作用,只下载主图像)
您可以使用curl
以下方法来检查您正在解析的 URL 是否存在,而无需下载任何文件:
if curl --head --fail --silent "$url" >/dev/null; then
touch .images/"${url##*/}"
fi
Run Code Online (Sandbox Code Playgroud)
解释:
--fail
将使请求失败时退出状态非零。--head
将避免下载文件内容--silent
将避免检查本身发出状态或错误。要解决“循环”问题,您可以这样做:
urls=( "${url%.jpg}"_{001..005}.jpg )
for url in "${urls[@]}"; do
if curl --head --silent --fail "$url" > /dev/null; then
touch .images/${url##*/}
fi
done
Run Code Online (Sandbox Code Playgroud)
很难理解你真正想要完成的是什么。让我试着重新表述你的问题。
我已经
urls.txt
包含:Run Code Online (Sandbox Code Playgroud)http://example.com/dira/foo.jpg http://example.com/dira/bar.jpg http://example.com/dirb/foo.jpg http://example.com/dirb/baz.jpg http://example.org/dira/foo.jpg
在
example.com
这些 URL 上存在:Run Code Online (Sandbox Code Playgroud)http://example.com/dira/foo.jpg http://example.com/dira/foo_001.jpg http://example.com/dira/foo_003.jpg http://example.com/dira/foo_005.jpg http://example.com/dira/bar_000.jpg http://example.com/dira/bar_002.jpg http://example.com/dira/bar_004.jpg http://example.com/dira/fubar.jpg http://example.com/dirb/foo.jpg http://example.com/dirb/baz.jpg http://example.com/dirb/baz_001.jpg http://example.com/dirb/baz_005.jpg
在
example.org
这些 URL 上存在:Run Code Online (Sandbox Code Playgroud)http://example.org/dira/foo_001.jpg
鉴于
urls.txt
我想生成与 _001.jpg .. _005.jpg 的组合以及原始 URL。例如:Run Code Online (Sandbox Code Playgroud)http://example.com/dira/foo.jpg
变成:
Run Code Online (Sandbox Code Playgroud)http://example.com/dira/foo.jpg http://example.com/dira/foo_001.jpg http://example.com/dira/foo_002.jpg http://example.com/dira/foo_003.jpg http://example.com/dira/foo_004.jpg http://example.com/dira/foo_005.jpg
然后我想在不下载文件的情况下测试这些 URL 是否存在。由于有很多 URL,我想并行执行此操作。
如果 URL 存在,我想要创建一个空文件。
(版本 1):我希望在 dir 中的类似目录结构中创建空文件
images
。这是必需的,因为一些图像具有相同的名称,但在不同的目录中。所以创建的文件应该是:
Run Code Online (Sandbox Code Playgroud)images/http:/example.com/dira/foo.jpg images/http:/example.com/dira/foo_001.jpg images/http:/example.com/dira/foo_003.jpg images/http:/example.com/dira/foo_005.jpg images/http:/example.com/dira/bar_000.jpg images/http:/example.com/dira/bar_002.jpg images/http:/example.com/dira/bar_004.jpg images/http:/example.com/dirb/foo.jpg images/http:/example.com/dirb/baz.jpg images/http:/example.com/dirb/baz_001.jpg images/http:/example.com/dirb/baz_005.jpg images/http:/example.org/dira/foo_001.jpg
(版本 2):我想要在 dir 中创建的空文件
images
。这是可以做到的,因为所有图像都有唯一的名称。所以创建的文件应该是:
Run Code Online (Sandbox Code Playgroud)images/foo.jpg images/foo_001.jpg images/foo_003.jpg images/foo_005.jpg images/bar_000.jpg images/bar_002.jpg images/bar_004.jpg images/baz.jpg images/baz_001.jpg images/baz_005.jpg
(版本 3):我想要在 dir 中创建的
images
名为 name from的空文件urls.txt
。这是可以做到的,因为只有 _001.jpg .. _005.jpg 之一存在。Run Code Online (Sandbox Code Playgroud)images/foo.jpg images/bar.jpg images/baz.jpg
#!/bin/bash
do_url() {
url="$1"
# Version 1:
# If you want to keep the folder structure from the server (similar to wget -m):
wget -q --method HEAD "$url" && mkdir -p images/"$2" && touch images/"$url"
# Version 2:
# If all the images have unique names and you want all images in a single dir
wget -q --method HEAD "$url" && touch images/"$3"
# Version 3:
# If all the images have unique names when _###.jpg is removed and you want all images in a single dir
wget -q --method HEAD "$url" && touch images/"$4"
}
export -f do_url
parallel do_url {1.}{2} {1//} {1/.}{2} {1/} :::: urls.txt ::: .jpg _{001..005}.jpg
Run Code Online (Sandbox Code Playgroud)
GNU Parallel 每个作业需要几毫秒。当你的工作这么短时,开销会影响时间。如果您的 CPU 内核均未以 100% 运行,您可以并行运行更多作业:
parallel -j0 do_url {1.}{2} {1//} {1/.}{2} {1/} :::: urls.txt ::: .jpg _{001..005}.jpg
Run Code Online (Sandbox Code Playgroud)
您还可以“展开”循环。这将为每个 URL 节省 5 次开销:
do_url() {
url="$1"
# Version 2:
# If all the images have unique names and you want all images in a single dir
wget -q --method HEAD "$url".jpg && touch images/"$url".jpg
wget -q --method HEAD "$url"_001.jpg && touch images/"$url"_001.jpg
wget -q --method HEAD "$url"_002.jpg && touch images/"$url"_002.jpg
wget -q --method HEAD "$url"_003.jpg && touch images/"$url"_003.jpg
wget -q --method HEAD "$url"_004.jpg && touch images/"$url"_004.jpg
wget -q --method HEAD "$url"_005.jpg && touch images/"$url"_005.jpg
}
export -f do_url
parallel -j0 do_url {.} :::: urls.txt
Run Code Online (Sandbox Code Playgroud)
最后,您可以运行 250 多个作业:https : //www.gnu.org/software/parallel/man.html#EXAMPLE : -Running- more-than-250-jobs- workaround
归档时间: |
|
查看次数: |
2657 次 |
最近记录: |