cat의 출력을 cURL로 파이프하여 파일 목록 다운로드


84

라는 파일에 목록 URL이 있습니다 urls.txt. 각 줄에는 1 개의 URL이 있습니다. cURL을 사용하여 한 번에 모든 파일을 다운로드하고 싶습니다. 나는 올바른 한 줄을 내리지 못하는 것 같습니다.

나는 시도했다 :

$ cat urls.txt | xargs -0 curl -O

그러나 그것은 목록의 마지막 파일만을 제공합니다.


11
for i in $(cat urls.txt) ; do curl -O $i ; done
bkconrad

1
감사합니다, @bkconrad. 나는 그것을 고정하지만 Windows에서 줄 바꿈에 문제가 있었다 tr:for i in $(cat urls.txt) ; do curl -O $(echo $i | tr '\r' ' ') ; done
biphobe

답변:


138

이것은 나를 위해 작동합니다.

$ xargs -n 1 curl -O < urls.txt

저는 FreeBSD에 있습니다. xargs가 다르게 작동 할 수 있습니다.

이것은 curl불필요하게 무겁게 보일 수있는 순차적 인 s를 실행 합니다. 그 오버 헤드의 일부를 저장하려면 bash에서 다음이 작동 할 수 있습니다.

$ mapfile -t urls < urls.txt
$ curl ${urls[@]/#/-O }

이렇게하면 URL 목록이 어레이에 저장되고 curl대상이 다운로드 되도록 하는 옵션이있는 어레이가 확장됩니다 . 이 curl명령은 여러 URL을 가져 와서 모두 가져 와서 기존 연결 (HTTP / 1.1)을 재활용 할 수 있지만 각 대상 -O다운로드하고 저장하려면 각 URL 앞에 옵션 이 필요합니다 . 일부 URL 내의 문자]는 셸과 상호 작용하지 않도록 이스케이프 처리해야 할 수 있습니다.

또는 bash가 아닌 POSIX 쉘을 사용하는 경우 :

$ curl $(printf ' -O %s' $(cat urls.txt))

이는 printf데이터 인수 목록을 소진하기 위해 형식 패턴을 반복하는의 동작에 의존합니다 . 모든 독립 실행 형 printf이이 작업을 수행하는 것은 아닙니다 .

이 xargs가 아닌 방법은 매우 큰 URL 목록에 대한 시스템 제한을 초과 할 수도 있습니다. 이것이 우려되는 경우 ARG_MAXMAX_ARG_STRLEN을 조사하십시오 .


이것은 작동하는 것처럼 보이지만 실제 파일 내용이 아닌 파일 이름이 포함 된 125 바이트 HTML 파일 만 제공 합니다.
핀치

1
아, 알겠습니다. 관련된 리디렉션이 있었으므로에 -L옵션을 추가해야 했습니다 curl.
핀치

4
힌트 주셔서 감사합니다! 그게 내 Mac에서 작업,하지만 난 파이프 라인 버전을 선호 cat urls.txt | xargs -n 1 curl -O;-)
orzechow

모든 작품,하지만 당신의 독서 즐거움, @Pio, 공평, unix.stackexchange.com/questions/16279/...
ghoti

이것은 훌륭하게 작동했습니다!. 그러나 나는 이것을 Windows의 git bash \r에서 사용했으며 텍스트 파일의 문자를 좋아하지 않았습니다 .
James McDonnell

34

매우 간단한 해결책은 다음과 같습니다. 'file.txt'파일이있는 경우

url="http://www.google.de"
url="http://www.yahoo.de"
url="http://www.bing.de"

그런 다음 curl을 사용하고 간단히

curl -K file.txt

그리고 curl은 file.txt에 포함 된 모든 URL을 호출합니다!

따라서 입력 파일 형식을 제어 할 수 있다면 이것이 가장 간단한 솔루션 일 것입니다!


1
HTTP 연결 유지를 사용합니까?
William Entriken

@FullDecent이 연결이 방법을 다시 사용
앨런 데몬

14

또는 다음과 같이 할 수 있습니다.

cat urls.txt | xargs curl -O

-I명령 중간에 cat 출력을 삽입하려는 경우 에만 매개 변수 를 사용하면 됩니다.


1
이것이 왜 투표되었는지 확실하지 않지만 완벽하게 작동하지만 입력을위한 플랫 텍스트 파일 대신 grep의 출력이 있습니다.
강탈

1
아마도 그것이 틀 렸기 때문에 반대 투표를했을 것입니다. -ocurl에 대한 옵션은 출력 파일을 인수로 지정합니다. 다른 답변 -O은 파일의 원격 이름을 기반으로 로컬 이름을 결정하도록 curl에 지시하는 권장 사항 입니다.
ghoti 2015

8

xargs -P 10 | curl

GNU xargs -P는 여러 curl프로세스를 병렬로 실행할 수 있습니다 . 예 : 10프로세스 실행 :

xargs -P 10 -n 1 curl -O < urls.txt

이렇게하면 최대 다운로드 속도에 도달하지 않고 서버가 가장 일반적인 시나리오 인 IP를 제한하지 않는 경우 다운로드 속도가 10 배 빨라집니다.

-P너무 높게 설정하지 마십시오. 그렇지 않으면 RAM이 압도 될 수 있습니다.

GNU parallel는 비슷한 결과를 얻을 수 있습니다.

이러한 방법의 단점은 모든 파일에 대해 단일 연결을 사용하지 않는다는 것 curl입니다. 다음과 같이 여러 URL을 한 번에 전달하면 어떻게됩니까?

curl -O out1.txt http://exmple.com/1 -O out2.txt http://exmple.com/2

/server/199434/how-do-i-make-curl-use-keepalive-from-the-command-line 에서 언급했듯이

두 가지 방법을 결합하면 최상의 결과를 얻을 수 있습니까? 하지만 병렬화가 연결을 유지하는 것보다 더 중요하다고 생각합니다.

참고 항목 : Curl 명령 줄 유틸리티를 사용한 병렬 다운로드


7

다음은 Mac (OSX)에서 수행하는 방법이지만 다른 시스템에서도 똑같이 잘 작동합니다.

필요한 것은 curl에 대한 링크가 포함 된 텍스트 파일입니다.

이렇게 :

    http://www.site1.com/subdirectory/file1-[01-15].jpg
    http://www.site1.com/subdirectory/file2-[01-15].jpg
    .
    .
    http://www.site1.com/subdirectory/file3287-[01-15].jpg

이 가상의 경우 텍스트 파일에는 3287 줄이 있고 각 줄은 15 개의 그림을 코딩합니다.

이러한 링크를 하드 드라이브의 최상위 레벨 (/)에있는 testcurl.txt라는 텍스트 파일에 저장한다고 가정 해 보겠습니다.

이제 터미널로 이동하여 bash 쉘에 다음 명령을 입력해야합니다.

    for i in "`cat /testcurl.txt`" ; do curl -O "$i" ; done

백틱 (`)을 사용하고 있는지 확인하십시오. 또한 플래그 (-O)가 대문자 O이고 0이 아닌지 확인하십시오.

-O 플래그를 사용하면 원래 파일 이름이 사용됩니다.

즐거운 다운로드 되세요!


변수 참조를 인용해야합니다. 누군가가 텍스트 파일에 특수 문자가있는 파일을 심으면 어떻게됩니까? 줄을 추가하고 echo ";sudo rm -rf ~/" >> testcurl.txt어떤 일이 발생하는지 확인하십시오.
ghoti 2014 년

4
^ 모르면하지 마십시오.
Rick Hanlon II

2
이것은 끔찍한 해결책입니다. 각 다운로드에 대해 별도의 프로세스를 생성 할뿐만 아니라 매번 TCP 연결을 다시 설정해야하므로 중간 대기 시간 네트워크에서도 많은 시간을 낭비하게됩니다.
cnst aug

4

다른 사람들이 올바르게 언급했듯이 :

-cat urls.txt | xargs -0 curl -O
+cat urls.txt | xargs -n1 curl -O

그러나이 패러다임은 특히 모든 URL이 동일한 서버에서 온 경우 매우 나쁜 생각입니다. 매우 비효율적이며 현재 유비쿼터스 https에서는 훨씬 더 그렇습니다.

대신 이것을 사용하십시오 :

-cat urls.txt | xargs -n1 curl -O
+cat urls.txt | wget -i/dev/fd/0

또는 더 간단합니다.

-cat urls.txt | wget -i/dev/fd/0
+wget -i/dev/fd/0 < urls.txt

가장 간단하지만 :

-wget -i/dev/fd/0 < urls.txt
+wget -iurls.txt

2
OP는 특히 curl로 이것을 수행하는 방법에 관한 것입니다. 아마도 이것은 curl이 이미 설치되어 있지만 wget은 설치되어 있지 않은 시스템 (예 : OSX)에서 사용하기위한 것일 수 있습니다. 또한 devfs에 의존 할 필요가 없으며 -i-stdin을 참조하는 데 사용할 수도 있습니다 . 즉 : wget -i- < urls.txt마지막으로, curl리스폰을 요구하지 않고 한 번에 여러 URL을 요청하려면 항상 명령 줄에 배치하면됩니다. xargs curl < urls.txtHTTP / 1.1을 사용하여이를 수행합니다. xargs가 처리 할 수있는 명령 줄 길이에 따라 URL 수가 제한됩니다. 이 한계를 getconf ARG_MAX.
ghoti
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.