CURL 출력을 명명된 아카이브 항목으로 직접 압축하려면 어떻게 해야 합니까?

CURL 출력을 명명된 아카이브 항목으로 직접 압축하려면 어떻게 해야 합니까?

원격 호스트에서 CURL 처리해야 하는 수백 개의 텍스트 파일이 있습니다.

현재 각 파일을 다운로드한 다음 새 파일로 압축하는 루프가 있습니다 .zip entry.

각 CURL의 결과가 아카이브 항목으로 사용되도록 CURL의 출력을 아카이브 유틸리티(zip, gzip, tar, rar 등 무엇이든 상관 없음)로 직접 파이프할 수 있습니까?

답변1

의 표준 출력이 터미널이 아닌 경우 curl다운로드한 콘텐츠를 파일에 쓰는 대신 터미널에 출력합니다. 그런 다음 이를 표준 입력을 읽는 다른 도구의 기능과 결합할 수 있습니다. 여러 항목이 포함된 아카이브를 생성하려면 사용할 이름을 알려줄 수 있는 도구를 사용해야 합니다.7z:

curl https://raw.githubusercontent.com/akka/akka/master/README.md | 7z a -siREADME.md akka.7z
curl https://raw.githubusercontent.com/akka/akka/master/RELEASING.md | 7z a -siRELEASING.md akka.7z

다음 콘텐츠를 포함하는 아카이브가 생성됩니다 akka.7z.README.mdRELEASING.md

$ 7z l akka.7z
   Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
2019-03-06 10:15:45 .....         3236         1457  README.md
2019-03-06 10:16:18 .....         3001         1437  RELEASING.md
------------------- ----- ------------ ------------  ------------------------
2019-03-06 10:16:18               6237         2894  2 files

( 7z모든 아카이브 형식이 지원되는 것은 아닙니다. 예를 들어 ZIP 파일에서 작동하도록 할 수 없습니다.)

답변2

-o에 대해 option(outputfile)을 사용하여 curl출력 파일을 -("stdout"을 의미하는 대시)로 지정하고 원하는 대로 파이프합니다.

~에서컬 맨 페이지:

-output <file>
          Write output to <file> instead of stdout. If you are using {} or [] to fetch multiple documents, you can use '#'
          followed by a number in the <file> specifier. That variable will be replaced with the current string for the URL
          being fetched. Like in:

            curl http://{one,two}.site.com -o "file_#1.txt"

          or use several variables like:

            curl http://{site,host}.host[1-5].com -o "#1_#2"

          You may use this option as many times as the number of URLs you have.

          See also the --create-dirs option to create the local directories dynamically. Specifying the output as  '-'  (a single dash) will force the output to be done to stdout.

좀 더 생각해 본 결과 원하는 결과를 얻은 것 같습니다. 다운로드한 각 파일은 다운로드 배치의 모든 파일을 포함하는 단일 아카이브가 아니라 선택한 아카이브/압축 형식으로 저장되어야 합니다. 내가 틀렸고 대상이 단일 파일이라면,답변~에서스티븐 지터더 나은 선택인 것 같습니다.

귀하의 목표에 따르면 귀하의 프로세스는 개선될 수 있지만 귀하가 원하는 수준까지는 개선될 수 없다고 생각합니다. 출력을 직접 파이핑하면 curl파일 이름이 손실됩니다. 그러나 루프를 통해 실행할 필요는 없습니다. 그렇게 하면 curl연결을 재사용하는 능력이 줄어들고 다중 연결/핸드셰이크 교환이 방지되며 속도가 향상됩니다. curl압축하는 동안 루프는 각 다운로드 사이에도 일시 중지됩니다. 내장된 확장 기능을 사용 curl하고 이를 채울 수 있는 방법이 있다고 가정합니다.

전용 다운로드 위치가 있고 통화 전에 해당 위치가 비어 있는 경우 curl해당 위치를 사용할 수 있습니다(아래 첫 번째 및 마지막 단계 제거). 그렇지 않으면 다운로드를 위한 임시 디렉터리를 만들어야 합니다. 최종 대상과 동일한 디스크 파티션에 있는 경우 "이동"은 간단하고 빠릅니다.

파일 목록이 생성되면 프로세스는 다음과 같습니다.

  • 임시 다운로드 디렉토리 생성
  • 한 번 호출 curl되고 전체 파일 목록이 포함됩니다.
  • curl파일 이름을 직접 정확하게 지정하고 다운로드 위치에 저장하세요.
  • find다운로드 위치에 전화하세요
  • 다운로드한 모든 파일을 보관 -exec하려면 옵션을 사용하세요 .find
  • 아카이브 파일을 저장 위치로 이동합니다.

단일 명령줄로 작업을 수행합니다.

mkdir -p temp_down && 
pushd temp_down >/dev/null && 
curl "http://www.arowtemple.com/{index,about,contact,directors,covens,temple,lessons,priesthood}.html" -o "#1.html" &&
find . -type f -exec sh -c 'zip -rms9T --move "$0.zip" "$0"' {} \; &&
popd >/dev/null

주목할 점은 세 번째와 네 번째 줄에 따옴표를 사용했다는 점입니다. 3행의 첫 번째 큰따옴표 세트는 Bash가 필요할 때 가져올 파일 목록으로 변수를 확장하는 동시에 Bash가 중괄호 내용을 확장하는 것을 방지합니다. 두 번째 그룹은 생성된 파일 이름을 쉘로부터 안전하게 만듭니다. curl중괄호 내용을 확장 하면 '#1'끝 부분이 검색된 각 파일의 파일 이름으로 대체됩니다. 4행의 작은따옴표는 하위 쉘로 전달될 때 명령을 그대로 유지하고 큰따옴표는 파일 이름을 쉘로부터 안전하게 유지합니다. 이러한 $0항목은 인쇄상의 오류가 아니므 $1로 의도한 대로 되어서는 안 됩니다.

다운로드를 모두 하나의 디렉터리에 수집해야 하는 경우 --create-dirs명령에서 해당 옵션을 제거할 수 있고, curl원본 파일과 보관된 버전을 유지하려는 경우 - 명령에서 해당 옵션을 제거할 수 있습니다 --move. 물론 이 명령은 원하는 아카이브/압축 프로그램으로 대체할 수 있습니다.findzipzip

관련 정보