我使用下面的函数下载一个大的 tar.gz 文件并同时解压缩。文件现在保存在 STDOUT 中。请问如何将它们移动到不同的文件目录?
wget -q -O - target URL | tar -zxvf -
答案1
它们不会在 STDOUT 上提取,但存档成员会作为相对路径提取当前工作目录。例如,如果存档包含名为/foo
、file1
、dir
、 和dir/file2
, dir/link -> file2
Members 的成员,并且当前工作目录为/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
当前工作目录。d
tar
tar
tar
对于某些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
,file1
和dir
文件。严格来说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/bar
为foo
),sort -u
删除重复项,并将xargs
每一行作为单独的参数传递给mv -t
。
不过,为了安全起见,您可能希望先将该列表保存到文件中以供检查,然后再进行重命名。
1 您至少需要O
使用 GNU tar 的选项,但是将存档中每个文件的内容发送到 stdout(例如,如果在终端中发出该命令,则用于显示)可能不是您想要的
²作为一种安全措施,大多数tar
实现在提取时都会从存档成员中剥离引导。/
如果存在以 开头的成员../
,则有些会完全跳过该成员,有些会删除组件../
。