web-dev-qa-db-ja.com

次の場所の後にリモートファイル名を取得するためのカール

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

事前に名前を知らなくてもファイルをダウンロードできれば素晴らしいでしょう。そうでなければ、リダイレクトされたファイルをコマンドライン経由で素早くプルダウンする別の方法はありますか?

69
Nick S.

リモート側は、Content-Dispositionヘッダーを使用してファイル名を送信します。

curl 7.21.2以降では、--remote-header-name/-J

curl -O -J -L $url
140
jmanning2k

curl(7.21.2以降)の最新バージョンがある場合は、 @ jmanning2kの答え を参照してください。

curlの古いバージョン(Snow Leopardに付属の7.19.7など)がある場合、2つの要求を実行します。応答ヘッダーからファイル名を取得するHEADと、GET

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
31

wgetの代わりにcurlを使用できる場合:

wget --content-disposition $url
11
JacekM

私はjmanning2kの答えにコメントしたかったのですが、新しいユーザーとしてはできないので、許可された彼の投稿を編集しようとしましたが、コメントであるはずだと言って編集は拒否されました。 ため息

とにかく、これを彼の回答へのコメントとして見てください。

これは、ヘッダーがfilename=pythoncomplete.vimは例と同じですが、一部のサイトはfilename*=UTF-8' 'filename.Zip' curl 7.28.0で認識されない

10
Diskutant

古いMacと新しい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"
6

不正に構成された特定のWebサーバーは、「ファイル名」をキーとして使用して名前を提供します。RFC2183では、「ファイル名」を指定しています。 curlは後者の場合のみを処理します。

2
drater

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
1
John Cooper