假设我有一个像这样的文件结构:
/
file0.txt
file00.txt
--folderA
fileA1.txt
fileA2.txt
--folderB
fileB.dat
fileB.txt
noisefile.noise123
--folderBB
fileBB1.dat
fileBB2.dat
fileBB.txt
noisefile.noise6hy
/
并使用以下命令创建一个 zip 文件(从):
zip -r archive.zip /*.txt /folderA/*.txt /folderB -x /folderB/noisefile.\*
该命令不保留原始文件结构,当我解压缩它时,它不会被解压缩到它曾经所在的位置。有没有办法使用或不使用(其他可用工具)来实现这一点zip
?
类似的类比是包含所有结构的.deb
文件data.tar.gz
,并且在安装时将其提取到原始位置。我不使用deb
文件的原因是因为它将被安装(注册?)在系统上,我想做的只是备份和恢复文件。也许deb
可以做我想做的,但我不知道?
一般方式
每个存储相对路径并在当前工作目录中提取文件的存档器都可以“强制”执行您想要的操作。你需要
/
) 创建一个存档(提供绝对路径可能就足够了,即使您在另一个目录中);所以
cd /
(或pushd /
)是至关重要的。这尤其适用于
zip
. 我将您的问题视为简化流程的要求,以摆脱cd /
. 相对于真正的工作目录解释目标文件(archive.zip
在问题中)的能力也很好;显然是后cd /
archive.zip
指/archive.zip
。和
tar
所需的功能在
tar
. 在 Linux 中,tar
是一个常见的归档器,虽然 POSIX 不需要(POSIX 归档器是pax
)。使用
tar
,它的--absolute-names
/-P
选项在您的情况下很有用。手册指出:有几个条件可以实现你想要的:
/*.txt /folderA/*.txt /folderB
中扩展为绝对路径。请注意,扩展 unquoted 的是外壳*
;然后tar
(或zip
在示例中)接收扩展路径。-P
(或--absolute-names
)。如果您不这样做,tar
则将存储每个路径而没有前导/
(您仍然可以在 中提取文件/
,这正是上面介绍的一般方式)。-P
再次使用。如果您不这样做,那么无论如何都会从每个路径tar
中删除前导/
,并且您将重新创建存储的目录树作为当前工作目录的子树。请注意,您仍然需要在提取时明确请求所需的行为,调整后的压缩命令是不够的。请参阅下一段以了解为什么这是一件好事。相对于一般方式的优势:
archive.tar
)可以指定为相对于真实工作目录的路径。补充说明:
zip
充当存档器和压缩器。这不太像 Unix(请参阅“做一件事并做好”)。如果要使用 压缩,请tar
压缩生成的存档或告诉在创建过程中即时tar
压缩。-r
启用递归的示例中。这tar
是默认行为。-x
排除某些文件的示例中。使用tar
它就像--exclude=/folderB/noisefile.\*
or--exclude='noisefile.*'
(这也将排除一个文件folderBB
)。读这个。例子:
为什么不默认提取绝对路径?
提取相对于当前工作目录的每个路径的默认行为是一件好事。这样,即使您是 root,您也不必担心某些存档(您希望仅在当前工作目录中提取文件)被证明是流氓并在其他地方提取文件(例如,它可能会覆盖
/etc/passwd
或其他)。您可以通过故意和明确地选择它来允许这种潜在的危险行为(使用先前cd /
或使用非默认选项,如tar -P
)。如果我真的想默认使用绝对路径怎么办?
这个别名
tar
将为交互式 shell 中的每个调用注入相关选项。或者,可以使用包装函数或包装脚本来注入选项。即使从另一个脚本调用包装脚本也很容易工作(为了比较:通常别名在脚本中不起作用)。一般方法也可以作为给定归档器的脚本来实现,尽管最基本的方法(仅
/
在调用真正的归档器之前将目录更改为)将导致相对路径被解释为相对于/
,无论当前工作目录如何. 这可以通过适当的命令行解析和内部逻辑来解决;但总的来说,这不是一项微不足道的任务。无论如何,我不建议更改默认行为。上一段解释了原因。如果我是你,我会接受在提取时需要非默认操作;我会在需要时故意执行它们。
提示
一般方式将您放在根目录中。您可能想要
cd
回到您真正的工作目录。有用的技巧:cd -
相当于cd "$OLDPWD" && pwd
。这是一个基本的cd
退路。pushd /
而不是cd /
,popd
最后。我知道键入cd /
and会更快cd -
,但是如果您/习惯于在日常工作中使用pushd
+popd
,那么您可能会在这种情况下自然地使用它们,无需再考虑,也不会破坏您的日常工作。一个子外壳,例如
(cd / && unzip …)
. 这不会更改主 shell 中的当前工作目录。这个技巧特别有用,因为变量在整个子shell执行之前就被扩展了;这意味着您可以$PWD
用来传递您的真实工作目录: