如何仅下载远程目录列表而非内容,以及从HTTPS/SFTP仓库获取目录内容以实现部分文件名匹配的自动下载
我完全明白你的处境——想自动下载一个只知道部分文件名的文件(比如带可变版本号的file-vers.x.y.z.zip),但wget和curl直接用通配符根本行不通。确实得先拿到远程目录的文件列表,筛选出目标文件,对比版本后再下载。下面我分HTTPS和SFTP两种场景,给你讲具体怎么获取目录列表,再补充点后续版本检查和下载的实用小技巧。
一、从HTTPS仓库获取目录列表
1. 当服务器开启目录索引时(访问目录能看到文件列表页面)
这种情况最直接,用wget或curl就能抓取目录列表,不下载文件:
用wget抓取列表:
用--spider参数开启“蜘蛛模式”,只爬取链接不下载内容,配合其他参数限制范围:wget --spider --recursive --no-parent --level=1 --output-file=dir_list.txt https://example.com/remote/dir/参数解释:
--spider:仅检查链接,不下载文件--recursive --level=1:只递归当前目录(不深入子目录)--no-parent:不向上爬取父目录--output-file:把爬取结果保存到文本文件里
之后用grep过滤匹配的文件名:
grep -E 'file-vers\.[0-9]+\.[0-9]+\.[0-9]+\.zip' dir_list.txt用curl抓取并过滤:
直接请求目录页面,然后用grep/sed提取文件名(需要根据页面HTML结构调整):# 先抓页面再过滤链接 curl https://example.com/remote/dir/ | grep -E 'file-vers\.[0-9]+\.[0-9]+\.[0-9]+\.zip' | sed -E 's/.*href="([^"]+)".*/\1/'这里的sed命令是从HTML的
<a href="文件名">标签里提取纯文件名,适配大多数默认的目录索引页面。
2. 当HTTPS仓库是API驱动时(比如GitHub Releases)
如果是像GitHub Releases这种通过API返回文件列表的场景,不用解析HTML,直接用curl+jq(轻量JSON解析工具)就能拿到目标文件的下载链接:
curl -s https://api.github.com/repos/OWNER/REPO/releases/latest | jq -r '.assets[] | select(.name | test("file-vers\\.[0-9]+\\.[0-9]+\\.[0-9]+\\.zip")) | .browser_download_url'
这个命令会直接返回最新版本中匹配文件名的下载链接,省去了手动筛选的步骤。
二、从SFTP仓库获取目录列表
SFTP的操作和HTTPS不同,主要用原生sftp命令或lftp工具来获取目录列表:
1. 用原生sftp命令(无需额外安装)
用批处理模式执行ls命令,避免交互:
# 把目录列表保存到文件 echo "ls" | sftp user@example.com:/remote/dir/ > dir_list.txt
同样用grep过滤目标文件名:
grep -E 'file-vers\.[0-9]+\.[0-9]+\.[0-9]+\.zip' dir_list.txt
2. 用lftp工具(更灵活)
如果需要更复杂的操作,比如直接过滤列表,推荐用lftp:
# 直接输出匹配的文件名 lftp -c "open sftp://user@example.com; cd /remote/dir; ls" | grep -E 'file-vers\.[0-9]+\.[0-9]+\.[0-9]+\.zip'
lftp支持多种协议,语法更接近本地shell,批量操作更方便。
三、后续:版本检查与自动下载
拿到匹配的文件名后,还可以对比本地已有的版本,只下载更新的文件。这里给你一个简单的脚本示例:
# 从目录列表中获取最新版本的文件名(按版本号排序) remote_file=$(grep -E 'file-vers\.[0-9]+\.[0-9]+\.[0-9]+\.zip' dir_list.txt | sort -V | tail -n 1) # 提取本地已有的最新版本号(如果存在) local_version=$(ls file-vers.*.zip 2>/dev/null | sort -V | tail -n 1 | sed -E 's/file-vers\.([0-9]+\.[0-9]+\.[0-9]+)\.zip/\1/') # 提取远程文件的版本号 remote_version=$(echo $remote_file | sed -E 's/file-vers\.([0-9]+\.[0-9]+\.[0-9]+)\.zip/\1/') # 对比版本,决定是否下载 if [ "$remote_version" \> "$local_version" ] || [ -z "$local_version" ]; then echo "发现新版本 $remote_version,开始下载..." # HTTPS下载示例 wget https://example.com/remote/dir/$remote_file # SFTP下载示例(替换成你的SFTP地址) # sftp user@example.com:/remote/dir/$remote_file . fi
sort -V是关键,它能按版本号的逻辑排序(比如1.10.0会排在1.9.0后面),比普通字符排序更准确。
备注:内容来源于stack exchange,提问作者Pietro




