如何直接将 CURL 输出压缩为命名存档条目?

如何直接将 CURL 输出压缩为命名存档条目?

我有数百个文本文件需要从远程主机进行 CURL 处理。

目前我有一个循环,它下载每个文件,然后将其压缩为新的.zip entry

是否可以将 CURL 的输出直接通过管道传输到存档实用程序(我不关心它的 zip、gzip、tar、rar 或其他任何内容...),以便将每个 CURL 的结果作为存档入口?

答案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选项 (输出文件) for 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 扩展大括号内容。第二组使创建的文件名保持 shell 安全。通过curl展开大括号内容,'#1'靠近末尾的部分将被替换为检索到的每个文件的文件名。第 4 行中的单引号使命令在传递到子 shell 时保持完整,双引号使文件名保持 shell 安全。这些$0条目不是拼写错误,它们不应该是$1预期的那样。

如果您的下载应该全部收集到一个目录中,您可以--create-dirs从命令中删除该选项curl,如果您希望保留原始文件和存档版本,请从-命令中删除该--move选项。当然,该命令可以替换为您选择的任何存档/压缩程序。findzipzip

相关内容