V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
iyaozhen
V2EX  ›  程序员

curl/wget 下载文件后我怎么知道文件名

  •  
  •   iyaozhen ·
    iyaozhen · 2015-08-29 22:27:43 +08:00 · 7967 次点击
    这是一个创建于 3407 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我想知道 curl/wget 下载的文件的文件名。

    http://stackoverflow.com/questions/6881034/curl-to-grab-remote-filename-after-following-location 这里介绍的方法是从 header 中获取,但有些下载服务器 header 里面并不包括文件名信息。

    比如说我

    wget https://update.pushbullet.com/pushbullet_installer.exe

    在 shell 脚本中我想获得 “ pushbullet_installer.exe ”, 已备后用。

    第 1 条附言  ·  2015-08-30 01:41:53 +08:00

    简单的实现:

    #!/usr/bin/env bash
    
    url=$1
    
    filename=$(curl -skIL $url | grep -o -E 'filename=.*$' | sed -e 's/filename=//')
    #trim
    filename="$(echo -e "${filename}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
    #未从 header 中获取到文件名
    if [ ${#filename} -le 1 ]
    then
        url_arr=(${url//\// })
        filename="${url_arr[-1]}"
    fi
    
    echo $filename
    
    22 条回复    2021-04-16 23:55:01 +08:00
    ljbha007
        1
    ljbha007  
       2015-08-29 22:30:05 +08:00
    curl http://www.baidu.com > baidu.html
    ljbha007
        2
    ljbha007  
       2015-08-29 22:30:25 +08:00   ❤️ 1
    搞错楼主意思了
    iyaozhen
        3
    iyaozhen  
    OP
       2015-08-29 22:33:03 +08:00
    @ljbha007 同样谢谢。眼睁睁的看着文件名获取不到呀。
    realpg
        4
    realpg  
       2015-08-29 22:34:21 +08:00   ❤️ 1
    wget -o 就能指定保存的名字 好像是-o 要不就是大写-O 吧 你自己 man wget 确认一下

    然后你就可以把这个名字用自定义的变量设置了,回头再用这个变量引用
    sparkrat
        5
    sparkrat  
       2015-08-29 22:36:47 +08:00   ❤️ 2
    sobigfish
        6
    sobigfish  
       2015-08-29 22:37:05 +08:00   ❤️ 1
    shell 字符串的截取
    http://www.cnblogs.com/ace9/archive/2012/08/31/2664920.html
    没验证过, lz 自己试验吧
    iyaozhen
        7
    iyaozhen  
    OP
       2015-08-29 22:40:06 +08:00
    @realpg 嗯, curl/wget 都有这个指令,这个方法我想过,但是我也不知道后缀。而且文件名指定为时间戳啥的我就不知道这个文件是哪个了。
    iyaozhen
        8
    iyaozhen  
    OP
       2015-08-29 22:43:32 +08:00   ❤️ 1
    @sparkrat 不要跑,就是看了文档不知道呀。
    iyaozhen
        9
    iyaozhen  
    OP
       2015-08-29 22:45:07 +08:00
    @sobigfish 截取 url 不行,这种下载的 url 就悲剧了。 http://www.vim.org/scripts/download_script.php?src_id=10872
    realpg
        10
    realpg  
       2015-08-29 22:45:09 +08:00
    @iyaozhen 那就字符串分割,用 shell 脚本内实现 split ,用 /分割取最后一段
    实现方法很多了, cut , tr 什么的都行自己随便找一种
    iyaozhen
        11
    iyaozhen  
    OP
       2015-08-29 22:47:02 +08:00
    @realpg 不完全行,请看楼上。
    realpg
        12
    realpg  
       2015-08-29 22:47:56 +08:00
    @iyaozhen
    wget 你上面的 URL 返回的本地下载文件名就是 download_script.php?src_id=10872
    不信你自己试去
    wget 也无法获取文件名
    iyaozhen
        13
    iyaozhen  
    OP
       2015-08-29 22:55:33 +08:00
    @realpg curl -J 可以。

    不过你这句话提醒了我。对于直接下载链接可以通过截取 url 获得文件名。对于类似 PHP 直接以文件流的方式输出文件的下载链接就可以读 header 了(按照规范,需要在 header 中指出文件名)。
    oott123
        14
    oott123  
       2015-08-30 07:42:29 +08:00 via Android
    你有没有想过,如果重名, wget 还会在文件名后面加数字…
    我觉得读取 wget 的 stdio 再正则取比较靠谱…
    firemiles
        15
    firemiles  
       2015-08-30 10:41:26 +08:00
    @iyaozhen 单独创建一个空目录,在该目录下 wget ,然后读取目录文件,这个方法比较二但应该行的通吧。
    iyaozhen
        16
    iyaozhen  
    OP
       2015-08-30 16:34:12 +08:00
    @oott123 不知道为什么,获取不到 wget 的输出。

    文件名我强制指定了,重名会覆盖。
    oott123
        17
    oott123  
       2015-08-30 16:35:49 +08:00
    @iyaozhen wget 应该是输出到 stderr 的。
    iyaozhen
        18
    iyaozhen  
    OP
       2015-08-30 16:43:53 +08:00
    @oott123 原来如此,谢谢指点。这样也是个好办法。

    还有一个问题是我重定向了输出,但我又想在终端看见输出( wget 的进度),应该怎么办?
    oott123
        19
    oott123  
       2015-08-30 16:45:06 +08:00
    @iyaozhen 可以考虑用 tee 来复制管道。
    iyaozhen
        20
    iyaozhen  
    OP
       2015-08-30 16:50:25 +08:00
    @oott123 谢谢,涨姿势了。^_^
    lizhenjia569
        21
    lizhenjia569  
       2021-04-16 23:51:54 +08:00
    我也是为了这个搞半天,最终效果还行吧,tee 管道会让下载进度条一行行显示,只能限制输出频率了:
    ```shell
    # sed 命令正则匹配分组引用: https://stackoverflow.com/a/58379307/11687405
    # 为了管道传给 sed 的同时下载信息打印到屏幕,使用 tee 命令重定向 stderr: https://stackoverflow.com/a/20553986/11687405
    # 添加 wget 参数--progress=dot:giga,避免小文件显示太多信息(显示一个点代表 1MB ): https://stackoverflow.com/a/35427299/11687405
    filename=$(wget --progress=dot:giga https://update.pushbullet.com/pushbullet_installer.exe 2>&1 | tee >(cat 1>&2) | sed -nr "s/.* - ‘(.+)’ saved .*/\1/p")
    echo 下载好的文件名为:$filename
    ```
    lizhenjia569
        22
    lizhenjia569  
       2021-04-16 23:55:01 +08:00
    我的写法返回的是下载完毕直接返回 wget 保存好的文件名
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2981 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 14:38 · PVG 22:38 · LAX 06:38 · JFK 09:38
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.