【问题标题】:Discard curl downloads below a minimum file size丢弃低于最小文件大小的 curl 下载
【发布时间】:2017-07-04 11:47:35
【问题描述】:

我经常需要通过curl 遍历一些图像下载,并希望丢弃那些低于特定文件大小的下载,因为它们显然不存在,即。 e.返回的“图像”是一个 404 页面。 curl 有一个 --max-filesize 选项,但没有一个用于最小文件大小的选项。

我正在考虑将URL图像位置和最小文件大小传递给脚本curlmin,例如

curlmin url 最小文件大小

我相信,由于我使用 [ ] 的字母数字系列序列来迭代数天,因此我需要能够“即时”删除低于特定文件大小的那些文件。我在下面的尝试还没有完成,因为我被困在如何在“if”语句中引用“当前”文件以及如何实际删除文件上。但也可能是我的一个班轮也无法正常工作。

#!/bin/bash
curl -O $1 | if [ $(wc -c <"$1") -le $2 ]; then delete_file_here; fi
                            ^^                  ^^^^^^^^^^^^^^^^

有什么想法吗?谢谢。

【问题讨论】:

  • curl 是您唯一的选择吗?为什么不wget
  • 我只安装了 curl。 wget 更适合这些东西吗?我的印象是curl 是一种“更现代”的方法(没有真正定义“现代”......),这些天更新得更好,使用更广泛。
  • wget 更适合您的用例 download the files that do exist
  • 哦,好吧,我想我应该看看安装wget 然后...
  • 我没有真正注意到你试图避免在远程文件不存在时创建文件。只需将-f 用于您的curl 命令即可。

标签: bash shell curl


【解决方案1】:

如果您只是希望curl 避免在远程文件不存在或请求/下载时出错时创建本地文件,只需使用-f 标志:

curl -fO "$1"

但是,如果您想删除低于特定大小的文件,这里有几个选项:

您可以使用parameter expansion 来获取文件名,以删除直到最后一个/ 的所有内容,例如${1##*/}

所以你可以这样做

curl -O "$1"
if [[ $(wc -c < "${1##*/}") -le $2 ]]; then
    rm -f "${1##*/}"
fi

或者我们可以使用find

curl -O "$1"
find . -type f -name "${1##*/}" -size -"$2"c -delete

假设您的find 支持-delete。否则,您可以将其替换为 -exec rm -f {} +

如果您的curl 命令可能会下载多个文件,您可以轻松调整find 命令以查找小于给定大小的目录结构中的所有文件。

最安全的路径是使用find,因为它不会被奇怪的文件名绊倒。如果做不到这一点,您可以尝试使用能够更好地支持这些操作的另一种语言。如果您确信您只有安全的名称,您可以尝试以下方法:

curl -O "$1" 2>&1 | awk -v min_size="$2" '/-->/ {"stat -c%s " $NF | getline s; if(s < min_size) {system("rm " $NF);}}'

这会将$2 作为变量min_size 传递给awk。然后我们将查看包含--&gt;curl 输出的每一行。这些行的最后一个字段(再次假设安全名称)是本地文件名,因此我们将调用stat 以获取大小(-c %s),然后检查该大小是否低于我们的min_size。如果是,请致电rm,再次相信我们有安全的名称,而不是包含IFS 或通配符等的名称。

【讨论】:

  • 它似乎并没有完全删除“动态”。如果我尝试./curlmin http://www.bom.gov.au/gms/IDE00135.201707[031630-041130].jpg 23000,其中 23000 比“无效”图像的 22,162 字节多一点,那么我仍然会下载所有这些。在此示例中,只有以 031630 和 041130 结尾的文件才是有效的图像。
  • @AlexIxeras 啊,curl 的 globbing 似乎与 bash 不同,所以参数扩展不是 a)像我第一次那样在一个文件上操作,b)找到下载的文件,c)肯定会在检查文件大小以将其删除之前下载文件。如果你不能在那里做 c),你可能需要切换到 shell 以外的另一种语言,比如使用 python 来下载文件,如果你需要检查头文件或其他东西
  • @AlexIxeras 一个可以接受的解决方案是将所有内容下载到一个干净的目录并从那里删除太小的文件?
  • 可以先下载文件,然后删除太小的文件。有没有办法在下载后立即删除太小的文件,或者解决方案是下载所有文件(即使它是 1000 秒)然后删除所有太小的文件? – 顺便说一句,正因为如此,我正在考虑像我在原始帖子中尝试过的那样通过管道输出,但不知道这是否真的有效。
  • @AlexIxeras 最安全的路径可能是下载它们并使用find,这样您就不必担心不安全的名称。如果你真的想在你去的时候删除并且确信没有人会为你漏掉危险的文件名,我提供了一个可能的解决方案——但我真的必须强调,如果有一个名为benign; rm -rf ~ 的文件,然后我们最终会执行该文件并删除您主目录中的所有内容
【解决方案2】:

使用wget和大括号展开[ Check here ]解决问题

wget http://www.bom.gov.au/gms/IDE00135.201707{031630..031637}.jpg

【讨论】:

  • 如果我调用./curlmin http://www.bom.gov.au/gms/IDE00135.201707[031630-031637].jpg,这只会创建一个名为IDE00135.201707[031630-031637].jpg 的文件。只有以 031630 结尾的文件才是有效图片。
  • 我忽略了可以有多个图像的事实。马上更新。
  • 命令wget http://www.bom.gov.au/gms/IDE00135.201707{031630..031637}.jpg是否只下载存在的文件?
  • @AlexIxeras 是的。它只下载那些存在的文件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-30
  • 2019-01-20
  • 1970-01-01
相关资源
最近更新 更多