![curl URL Globbing 全解:用 `{}` 列表与 `[]` 范围一次批量生成并抓取 URL](http://pic.xiahunao.cn/yaotu/curl URL Globbing 全解:用 `{}` 列表与 `[]` 范围一次批量生成并抓取 URL)
curl URL Globbing 全解用{}列表与[]范围一次批量生成并抓取 URL【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl本指南以 curl 命令行工具的 URL globbing 机制为主题文档主体见 docs/cmdline-opts/_GLOBBING.md系统讲解如何在一条命令行里用{}花括号列表和[]方括号范围批量生成大量 URL以及如何借助--output的数字/命名引用把展开结果落到不同文件。读完你不仅能熟练写出可复用的批量下载命令还能从 src/tool_urlglob.c 与 src/tool_operate.c 的源码层面理解语法校验、范围展开与里程表式组合生成的真实实现。URL Globbing 是什么curl 允许在一个 URL 参数内部写出多个取值从而一次命令行批量请求多个 URL这套机制官方称之为 globbingURL 通配/展开你可以在 URL 中通过花括号{}内的列表或方括号[]内的范围来指定多个 URL 或 URL 的一部分curl 称之为 globbing。与 shell 通配符不同它是curl 自己在发起请求之前解析并逐一展开的因此即使 shell 不做任何扩展、甚至把整条 URL 放进引号curl 依然能生成一串真实 URL并按序逐一请求。需要特别说明这一解析发生在外层curl * URL主调用链中src/tool_operate.c 中先以glob_url()把带模式串解析为内部结构、再以glob_next_url()逐个产出 URL与 libcurl 库 API 无关——它是 curl 命令行工具层的便捷能力文档见 docs/cmdline-opts/url.md 中对命令行多 URL 语义的介绍。从实现上看展开引擎把所有模式串解析为一串URLPatternsrc/tool_urlglob.h每个 pattern 记录一种类型GLOB_SET{}列表、GLOB_ASCII字母范围、GLOB_NUM数字范围三类组合起来足以覆盖文档中的全部语法typedef enum { GLOB_SET 1, GLOB_ASCII, GLOB_NUM } globtype;用{}列举多个候选值最简单的形式是在花括号内用逗号分隔多个候选片段curl 会为每一个候选值生成一个 URLhttps://fun.example/{one,two,three}.jpg等价于依次请求https://fun.example/one.jpghttps://fun.example/two.jpghttps://fun.example/three.jpg{}片段可以出现在 URL 的任意位置不一定只在末尾也不受协议限制例如把候选值放在主机名部分的 SFTP 地址同样成立sftp://{one,two,three}.example/README该写法解析为逐一拉取sftp://one.example/README、sftp://two.example/README、sftp://three.example/README。从源码看{}列表由glob_set()实现src/tool_urlglob.c它把,分隔的每个片段复制为独立元素存入elem数组遇到}结束收集元素允许为空字符串但紧贴花括号内没有内容如{one,}不会出错{}即空字符串在括号内会报错见 src/tool_urlglob.c 对empty string within braces的判定。用[]声明连续范围方括号用于声明一段连续的序列包括数字和字母两种数字范围例如下载file1.txt到file100.txtftp://ftp.example.com/file[1-100].txt带前导零的范围。写法上多写几个零即可curl 会保持位数对齐地补齐前导零ftp://ftp.example.com/file[001-100].txt即请求file001.txt、file002.txt…file100.txt。源码中该行为由数字范围的npadpadding 位数字段体现解析时若发现范围以0开头会统计前导零个数生成时使用%0*d格式按该位宽补零src/tool_urlglob.c 与 src/tool_urlglob.c。字母范围从头到尾把字母表当作序列ftp://ftp.example.com/file[a-z].txt上述命令生成filea.txt到filez.txt共 26 个 URL。字母范围同样支持大写但源码校验要求范围两端必须处于同一大小写域且升序合法否则判定为bad rangesrc/tool_urlglob.c。加步进每隔 N 个取一个范围语法支持追加:step指定步长得到每第 N 个取值。数字与字母都适用# 取 1、11、21、…、91 https://example.com/file[1-100:10].txt # 取 a、c、e、… 每隔 2 个字母 https://example.com/file[a-z:2].txt步进在校验与生成两层都被实现解析阶段记录step并据此计算展开数量src/tool_urlglob.c展开阶段每次把当前游标 step直到越过maxsrc/tool_urlglob.c。注意源码同时对步长做了合法性约束min max时步长必须为 1且step不能超过max - min违反即报bad range因此请勿写出[1-5:10]这类语义无意义的模式。嵌套不支持但可并列组合glob 语法不支持嵌套——即不能在{}里再写{}/[]也不能在[]里嵌套。如果你写了嵌套curl 会直接报错。对应源码中glob_set()扫描到{或[会返回nested brace错误src/tool_urlglob.c。不过你可以把多个 glob 一个挨一个地并列书写它们会被做笛卡尔积式的组合展开效果上等价于嵌套。官方示例同时演示了三个相邻 globhttps://example.com/archive[1996-1999]/vol[1-4]/part{a,b,c}.html该 URL 一共会展开为4 × 4 × 3 48个 URL1996~1999 四个年份 × vol1~4 四个卷 × part a/b/c 三个分支。从 src/tool_urlglob.c 的glob_next_url()可看到组合的具体驱动方式它维护每个 pattern 的当前游标像里程表/计数器一样从最右侧 pattern 开始递增走到末尾就回绕并把进位传给左边一个 pattern当最左侧 pattern 也发生回绕时全部组合耗尽。顺序上先保持左侧取值不动、最右侧变化最快逐条产出。由于展开数量 各 glob 规模的乘积源码在解析阶段对总数量做乘法和溢出保护multiply()src/tool_urlglob.c单个列表元素超过 100000 也会以range overflow报错——实际使用中请避免一次性展开几十万条 URL。引号与 shell 干扰问题在命令行直接写含[]、{}的 URL 时bash/zsh 等 shell 可能先于 curl 对它们做通配展开或语法解析例如中括号恰好匹配到当前目录下的文件花括号被 shell 当作 brace expansion从而破坏你的本意。因此官方建议当 URL 中用到[]/{}序列时把完整 URL 用双引号包起来curl https://fun.example/{one,two}.jpg该告诫同样适用于 URL 中出现的其他 shell 特殊字符例如、?与*。把 URL 放入双引号后shell 不再干预curl 才能可靠地拿到原始模式串。更稳妥的做法是把它写进配置文件--config或脚本变量再引用。让--output复用展开片段#N位置引用当一次展开抓取多个 URL 时默认所有响应会拼接输出到 stdout几乎没法用。curl 的--output-o选项因此内置了glob 片段引用语法在输出文件名里写#加数字该数字对应 URL 中第 N 个从 1 开始计数glob 片段会被替换为当前这一条 URL 正在使用的那个取值。典型例子见 docs/cmdline-opts/output.mdcurl http://{one,two}.example.com -o file_#1.txt这条命令分别把one.example.com与two.example.com的响应保存为file_one.txt与file_two.txt。也可以一次引用多个片段、并且把片段拼在输出文件名任意位置curl http://{site,host}.host[1-5].example -o #1_#2这里#1对应{site,host}、#2对应[1-5]于是产出site_1、site_2…host_5等一组文件。多 URL 多-o时两者的对应规则是按位置配对第几条 URL 就用第几个-o即文档所说 first-ois for the first URL且命令行书写顺序无关URL 与选项可任意混排见 docs/cmdline-opts/output.md 中-o aa example.com -o bb example.net的等价两种写法。内部实现上输出文件名模板的解析在glob_match_url()中完成src/tool_urlglob.c遇到#后紧跟数字时它会解析出序号、寻找globindex匹配的那个 pattern并把当前展开值注入文件名若该序号没有对应 glob比如编号为 0 或越界则按普通字符原样保留。8.21.0 起的命名 glob{nameone,two}与#name从curl 8.21.0开始每个独立的 glob 部分还可以显式命名并在--output中按名字引用。名字是区分大小写的字母数字串写法是在{或[之后、紧跟一对尖括号...https://fun.example/{numberone,two}.jpg ftp://ftp.example.com/file[range1-100].txt随后输出文件名即可通过#名字引用对应片段curl https://fun.example/{numone,two}.jpg -o save-#num curl ftp://ftp.example/file[range1-100].txt \ -o save-#range.txt命名引用比数字引用更可读、也更健壮即使 URL 中 glob 的数量或次序调整只要名字不变-o引用依然准确。需要注意同一个 glob 名字重复定义两次是错误解析阶段会报Duplicate glob name见 src/tool_urlglob.c名字长度上限为 64 字符MAX_GLOBNAME_LENsrc/tool_urlglob.c在-o中引用了不存在的名字会报错no glob exists with this namesrc/tool_urlglob.c而数字引用越界时则被宽容地按普通字符保留。命名 glob 的查找按大小写敏感比较完成glob_find_name()src/tool_urlglob.c查找范围同时覆盖 URL 的 glob 列表与上传文件名的 glob 列表——这正是下面的上传场景能跨参数引用的原因。上传文件名同样支持 globbing--upload-file-T的本地文件名参数也支持这套 globbing 语法因此可以上传多个文件到同一个 URL其中命名的 glob 片段还能用于-o里为每个上传请求单独保存响应。官方示例docs/cmdline-opts/upload-file.md、docs/cmdline-opts/output.mdcurl -T file{num1,2,3} \ https://upload.example/ -o response-#num该命令把file1、file2、file3依次上传到https://upload.example/并把三次响应分别写入response-1、response-2、response-3。实现上上传文件名模式会单独解析到state-inglobURL 模式解析到state-urlglob两个结构并存在 src/tool_cfgable.hglob_match_url()查找命名 glob 时依次检索这两个列表src/tool_urlglob.c因此-T里定义的名字才能被-o正确解析到。关闭 globbing--globoff-g某些 URL 会天然包含{}或[]字符——虽然按 URI 标准它们并非合法 URL 字符、本应做百分号编码但现实中你仍可能收到这样的地址。若不想让 curl 展开可关闭 globbingcurl -g https://example.com/{[]}}}}--globoff短选项-g自 7.6 引入详见 docs/cmdline-opts/globoff.md让 curl 把整条 URL 当作普通字面量、不做任何{}/[]展开。设置后 URL 中出现的{}[]都会被原样传送而不会触发列表/范围解析或各种 unmatched brace 之类的报错。一个与之配套的贴心细节是数字形式的 IPv6 地址天然使用[...]括起来curl 能自动识别并放行这类字面量把它们从 globbing 处理中排除见 docs/cmdline-opts/globoff.md。源码中peek_ipv6()会扫描潜在的 IPv6 字面量——它含两个以上冒号且不含连字符因此明显区别于含一个连字符的数字范围识别为 IPv6 后整段[...]会被跳过、不参与范围解析src/tool_urlglob.c 与 src/tool_urlglob.c所以curl http://[::1]/这类命令无需-g也能正常工作。常见错误与调试提示解析失败时 curl 会报curl: (3) ...URL 格式错误类并尽可能指示出错位置。glob_show_error()会把错误消息连同列位置一并打印并在 URL 原文下方用^指向出错字符src/tool_urlglob.c。下面是可能遇到的代表性错误消息及含义报错消息触发场景修复建议unmatched brace{}有头无尾检查是否缺少}nested brace在{}/[]里嵌套写了{}或[]改成并列的多个 globunmatched close brace/bracket单独出现多余的}或]检查括号配对或用--globoffbad range[内不是合法数字/字母范围或范围降序、步长超界检查[min-max]、[a-z]写法与步长range overflow展开数量超过上限或乘法溢出缩小范围/列表规模Duplicate glob name同一个name定义了两次改不同的名字no glob exists with this name-o引用了未定义的名字在 URL/上传文件名中定义该名字若只是不想让某条含特殊字符的 URL 触发展开直接加-g即可。结合测试理解行为仓库的集成测试直接用真实 URL 验证了上述行为可作为你排查问题的对照基准tests/data/test74{}列表检索 -o dumpit#1.dump数字引用的端到端用例tests/data/test75[]范围写错bad range时应有的报错行为tests/data/test86[]范围检索 -o #N引用的组合tests/data/test87-o #N引用编号越界时的处理。小结curl 的 URL globbing 是命令行批量抓取的高效工具核心要点可归纳为四点{}做离散列表、[]做数字/字母连续范围可前导补零、可步进、相邻 glob 做笛卡尔积组合、用-o #N/-o #name把展开值映射到独立文件。语法解析、范围校验与里程表式的展开都在 src/tool_urlglob.c 中实现理解了它你既能写出稳健的批量命令注意 shell 引号与--globoff也能在遇到报错时快速定位是哪一段模式写得不合规范。若想继续深挖相关实现与文档入口为官方语法文档主体docs/cmdline-opts/_GLOBBING.md命令行引用文档docs/cmdline-opts/output.md、docs/cmdline-opts/globoff.md、docs/cmdline-opts/upload-file.md、docs/cmdline-opts/url.md核心实现src/tool_urlglob.c、src/tool_urlglob.h、调用方 src/tool_operate.c集成测试tests/data/test74、tests/data/test75、tests/data/test86、tests/data/test87【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考