请问使用边下载边提取功能后如何检索保存在 STDOUT 中的文件?

请问使用边下载边提取功能后如何检索保存在 STDOUT 中的文件?

我使用下面的函数下载一个大的 tar.gz 文件并同时解压缩。文件现在保存在 STDOUT 中。请问如何将它们移动到不同的文件目录?

wget -q -O - target URL | tar -zxvf -

答案1

它们不会在 STDOUT 上提取,但存档成员会作为相对路径提取当前工作目录。例如,如果存档包含名为/foofile1dir、 和dir/file2, dir/link -> file2Members 的成员,并且当前工作目录为/home/sosa,则将创建/home/sosa/foo², /home/sosa/file1, /home/sosa/dir, /home/sosa/dir/file2,文件。/home/sosa/dir/link

如果您希望将它们提取为不同目录的相对路径,您可以使用:

wget -q -O - URL | (cd some/other/directory && tar -zxvf -)

也就是说,在执行提取相对于那里的存档成员之前,挂起将要执行的进程的c当前工作目录。dtartartar

对于某些tar实现,您还可以使用-C以下选项:

wget -q -O - URL | tar -C some/other/directory -zxvf -

如果您已经在当前工作目录中提取了存档,但希望将文件移动到其他地方,那么您需要确定当前目录中的哪些文件是从存档中提取的,哪些文件已经存在。

如果您在过去 10 分钟内提取了存档,并且在该时间间隔内当前目录中没有其他文件被触及,则zsh可以执行以下操作:

mv -- *(Dcm-10) /some/other/dir/

对于带有最后更改时间在最后 10 分钟内移动到/some/other/dir/

find或者使用和的 GNU 实现mv

find . -mindepth 1 -maxdepth 1 -cmin -10 -exec mv -vt /some/other/dir {} +

在上面的示例中,这将移动foo,file1dir文件。严格来说dir/file2和文件dir/link不会移动,它们仍然链接到该dir目录,但随着目录的dir移动,它们的新完整路径将是/some/other/dir/dir/file2, /some/other/dir/dir/link

如果您无法隔离可识别文件的时间窗口,则需要再次下载存档以检索存档成员列表,并提取每个文件的第一个路径部分。假设存档成员不包含换行符,在 GNU 系统上,您可以这样做:

xargs -rd'\n' -a <(
  wget -qO- URL |
    tar -ztf - |
    LC_ALL=C sed -E 's@^((|\.|\.\.)/)*@@; s@/.*@@; /^(|\.|\.\.)$/d' |
    LC_ALL=C sort -u) mv -vt some/other/dir --

下载wget存档tar-t列出其内容,sed删除前导/, ./,../组件 以及除第一个路径组件之外的所有组件(将所有foo/bar,转换/foo/bar /.././../foo/barfoo),sort -u删除重复项,并将xargs每一行作为单独的参数传递给mv -t

不过,为了安全起见,您可能希望先将该列表保存到文件中以供检查,然后再进行重命名。


1 您至少需要O使用 GNU tar 的选项,但是将存档中每个文件的内容发送到 stdout(例如,如果在终端中发出该命令,则用于显示)可能不是您想要的

²作为一种安全措施,大多数tar实现在提取时都会从存档成员中剥离引导。/如果存在以 开头的成员../,则有些会完全跳过该成员,有些会删除组件../

相关内容