我有数百个文本文件需要从远程主机进行 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.md
RELEASING.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
选项。当然,该命令可以替换为您选择的任何存档/压缩程序。find
zip
zip