我要下载部分一个大的 (199GB) .tar.gz 文件这里。首先,我使用以下命令列出 .tar.gz 文件中的所有文件:
wget -qO- https://www.cs.cornell.edu/projects/megadepth/dataset/Megadepth_v1/MegaDepth_v1.tar.gz | tar -tz
接下来,我尝试使用以下命令下载 .tar.gz 中文件夹的内容:
wget -qO- https://www.cs.cornell.edu/projects/megadepth/dataset/Megadepth_v1/MegaDepth_v1.tar.gz | tar -xz phoenix/S6/zl548/MegaDepth_v1/0000
但是,这花费的时间太长,因为该tar
命令会深度优先并递归地搜索下面的每个文件夹phoenix/S6/zl548/MegaDepth_v1
。我只对文件夹的内容感兴趣phoenix/S6/zl548/MegaDepth_v1/0000
。有没有办法下载该文件夹的内容,而无需搜索其他文件夹的子文件夹,例如
phoenix/S6/zl548/MegaDepth_v1/0162
phoenix/S6/zl548/MegaDepth_v1/0001
phoenix/S6/zl548/MegaDepth_v1/0132
换句话说,有没有更快的方法来下载文件夹的内容phoenix/S6/zl548/MegaDepth_v1/0000
?
上述命令的一些参考:
答案1
tar
写入文件头,然后写入文件内容,然后写入下一个文件头,下一个文件内容,依此类推。
条目没有关联的顺序,您可以想到的唯一优化是跳过文件的内容,直接查找下一个标头。为此,您需要有一个可查找的文件。
但是您的内容.gz
已被压缩,因此您没有可靠的方法可以跳到下一个条目,这意味着您将必须读取(下载)整个文件以获取内容。这就是答案:不,您无法避免阅读/下载整个文件。
因此,由于无论如何您都必须完全下载它,因此您最好只下载一次,然后解决本地文件系统中的所有问题。
答案2
答案3
每次执行时wget
,您都在尝试下载整个 tar 文件!您可能已经多次下载“初始内容”,并通过将输出发送到 stdout 将其丢弃!
相反,“更快”的方法是将其下载一次到当前目录中的 ./MegaDepth_v1.tar.gz 并在那里解压缩。
wget -q -O MegaDepth_v1.tar.gz https://www.cs.cornell.edu/projects/megadepth/dataset/Megadepth_v1/MegaDepth_v1.tar.gz
tar -xz -f MegaDepth_v1.tar.gz phoenix/S6/zl548/MegaDepth_v1/0000
获得必要的文件后,您可以删除下载的 tar 文件。
更新:原始文件的大小似乎约为 200 GB。下载本身会占用大量的时间和空间。提取将花费额外的时间。没有赢, 在这种情况下!
您可能需要联系 MegaDepth 团队并要求他们提供单独的目录访问权限,否则速度总是很慢。
在这里,wget
无法跳过不需要的内容,并且始终会从头到尾下载整个 tar 文件。此外,(如用户 ilkkach 的回答中所述)tar
无法跳过(或查找)stdout 流。
答案4
分析
我同意其他答案,说没有办法tar
寻找压缩档案。要找到您要查找的文件,该工具需要从头开始处理存档,而不是跳过任何内容。
然而,对于 GNU,tar
您不一定需要将其处理到底。创建存档时请考虑以下场景:
假设您更改文件
blues
,然后将更改后的版本附加到collection.tar
. [...],原件blues
在档案中collection.tar
。如果更改文件并将新版本的文件附加到存档中,则存档中将有两个副本。当您提取存档时,将首先提取文件的旧版本,然后在提取时替换为新版本。
(来源)
这意味着,在提取特定文件时,tar
即使在提取文件后也会继续处理存档,因为存档中可能稍后有另一个副本。
但是之后:
blues
如果您希望从存档中提取文件的第一次出现,请使用--occurrence
选项
(同上)
如果您确定您要查找的文件在存档中仅出现过一次,请使用tar --occurrence
和tar
将在解压文件后停止。然后你的wget
将由于 中止SIGPIPE
,它不会白白下载档案的其余部分。
用途有限
笔记这对你来说并不是很有用精确的案例因为phoenix/S6/zl548/MegaDepth_v1/0000
是一个目录(对吗?)。使用--occurrence
,提取目录时tar
不会提前停止,除非遇到该目录的另一个条目本身。原因是:phoenix/S6/zl548/MegaDepth_v1/0000/foo
档案的最后总是有一个唯一的。在tar
结束之前,无法确定目录及其所有内容是否完整。
不过,如果你想要一个或几个非目录,如果您知道路径并且知道存档中每个路径只有一个实例,则将--occurrence
允许您根据需要下载尽可能少的存档。如果您很幸运并且文件恰好位于存档的开头附近,那么--occurrence
将会产生显着的差异。
也许这个答案不会对你有太大帮助。适用于可以提供以下列表的用户非目录。
除非…
如果您保存了输出wget -qO- … | tar -tz
(当您很可能下载并处理整个存档并将其丢弃时),您现在可以提供以下列表非目录(可能使用--files-from=
或--verbatim-files-from
;如果列表对于单个命令行来说太长,则特别有用)。在这种情况下--occurrence
可能适合你。此外,保存的输出tar -t
将允许您确认您所查找的每个非目录在存档中仅出现一次,因此您知道--occurrence
不会让您错过更新的版本。
上面的假设MegaDepth_v1.tar.gz
在服务器上没有改变。一般来说(如果存档可能已更改)您保存的输出tar -t
可能不再有效。
假设您可以创建要提取的非目录列表。该清单必须不是明确指定任何目录,否则--occurrence
不会帮助您。仍然tar
会创建必要的目录,但只是为了将非目录放入其中,而不是因为它会真正从存档中提取目录。换句话说:目录本身的存档成员并不重要。这意味着将创建目录,但类似的选项--preserve-permissions
不适用于它们。
概念证明
我使用了您的第一个命令(带有 的命令tar -t
)并发现这phoenix/S6/zl548/MegaDepth_v1/0162/dense0/depths/16384199365_2b34b42cf4_b.h5
是靠近存档开头的非目录。该管道:
wget -qO- https://www.cs.cornell.edu/projects/megadepth/dataset/Megadepth_v1/MegaDepth_v1.tar.gz \
| tar -xvz phoenix/S6/zl548/MegaDepth_v1/0162/dense0/depths/16384199365_2b34b42cf4_b.h5
提取文件并继续(我可以Ctrl+ c);但这一个:
wget -qO- https://www.cs.cornell.edu/projects/megadepth/dataset/Megadepth_v1/MegaDepth_v1.tar.gz \
| tar --occurrence -xvz phoenix/S6/zl548/MegaDepth_v1/0162/dense0/depths/16384199365_2b34b42cf4_b.h5
提取文件并自动终止。