卷曲以获取以下位置后的远程文件名

时间:2011-07-30 04:15:37

标签: unix command-line curl

使用curl下载文件时,如何跟踪链接位置并将其用于输出文件名(事先不知道远程文件名)?

例如,如果点击下面的链接,你会下载一个名为“pythoncomplete.vim”的文件名。但是使用curl的-O和-L选项,文件名只是原始的远程名称,笨拙的“download_script.php?src_id = 10872。”

curl -O -L http://www.vim.org/scripts/download_script.php?src_id=10872

要下载具有正确文件名的文件,您必须提前知道该文件的名称:

curl -o pythoncomplete.vim -L http://www.vim.org/scripts/download_script.php?src_id=10872

如果您可以在不事先知道名称的情况下下载文件,那将是非常好的,如果没有,是否有另一种方法可以通过命令行快速下载重定向文件?

9 个答案:

答案 0 :(得分:135)

远程端使用Content-Disposition标头发送文件名。

如果您指定--remote-header-name / -J

卷曲7.21.2或更新会自动执行此操作。

curl -O -J -L $url

答案 1 :(得分:31)

如果您的最新版本为curl(7.21.2或更高版本),请参阅@jmanning2k's answer

我有curl的旧版本(如雪豹附带的7.19.7),做两个请求:HEAD从响应头获取文件名,然后是{GET 1}}:

url="http://www.vim.org/scripts/download_script.php?src_id=10872"
filename=$(curl -sI  $url | grep -o -E 'filename=.*$' | sed -e 's/filename=//')
curl -o $filename -L $url

答案 2 :(得分:10)

我想评论jmanning2k的答案,但作为一个新用户我不能,所以我试图编辑他的帖子是允许但编辑被拒绝说它应该是评论。 叹息

无论如何,请将此视为对他的回答的评论。

这似乎仅在标题看起来像示例中的filename=pythoncomplete.vim时才有效,但有些网站会发送一个看起来像filename*=UTF-8' 'filename.zip'的标题,其中一个标题不会被curl 7.28.0识别

答案 3 :(得分:9)

如果您可以使用wget代替curl

wget --content-disposition $url

答案 4 :(得分:6)

我想要一个适用于旧版和新版Mac的解决方案,David为Snow Leopard提供的遗留代码在Mavericks下表现不佳。这是我根据David的代码创建的函数:

function getUriFilename() {
    header="$(curl -sI "$1" | tr -d '\r')"

    filename="$(echo "$header" | grep -o -E 'filename=.*$')"
    if [[ -n "$filename" ]]; then
        echo "${filename#filename=}"
        return
    fi

    filename="$(echo "$header" | grep -o -E 'Location:.*$')"
    if [[ -n "$filename" ]]; then
        basename "${filename#Location\:}"
        return
    fi

    return 1
}

通过此定义,您可以运行:

url="http://www.vim.org/scripts/download_script.php?src_id=10872"
filename="$(getUriFilename $url)"
curl -L $url -o "$filename"

答案 5 :(得分:2)

请注意,某些配置错误的网络服务器将使用“文件名”作为密钥提供名称,其中RFC2183指定它应为“文件名”。 curl只处理后一种情况。

答案 6 :(得分:1)

使用上面的答案为Apache Archiva工件库提取最新版本的示例。 curl返回Location行,文件名位于行尾。需要删除文件名末尾的CR。

url="http://archiva:8080/restServices/archivaServices/searchService/artifact?g=com.imgur.backup&a=snapshot-s3-util&v=LATEST"
filename=$(curl --silent -sI -u user:password $url | grep Location | awk -F\/ '{print $NF}' | sed 's/\r$//')
curl --silent -o $filename -L -u user:password $url

答案 7 :(得分:0)

我有和约翰·库珀一样的问题。我没有文件名,但返回了位置文件名。他的回答也有用,但是有两个命令。 这个班轮为我工作。...

url="https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64&lang=de";url=$(curl -L --head -w '%{url_effective}' $url 2>/dev/null | tail -n1) ; curl -O $url

窃取并添加了一些内容 https://unix.stackexchange.com/questions/126252/resolve-filename-from-a-remote-url-without-downloading-a-file

答案 8 :(得分:0)

使用建议的解决方案 above,我编写了这个辅助函数 curl2file

function curl2file() {
    url=$1
    url=$(curl -L --head -w '%{url_effective}' $url 2>/dev/null | tail -n1) ; curl -O $url
}

用法:

curl2file https://cloud.tsinghua.edu.cn/f/4666d28af98a4e63afb5/?dl=1