Python实现不解压修改Tar文件内目录为根路径(替代7-zip操作)
如何在Python创建TAR时将目录映射为绝对路径(等效7-zip重命名为
/dir1) 问题背景
现有一个TAR文件,原始结构如下:
├── dir1 │ ├── sub-dir1 │ │ ├── file1 │ │ ├── file2 │ ├── sub-dir2 │ │ ├── file3 │ ├── file4 ├── dir2 │ ├── file5 ├── dir3 │ ├── file6 │ ├── file7
同事通过7-zip打开TAR,将dir1重命名为/dir1后,在RHEL机器上解压时,dir1下的内容会直接被放到系统根目录的/dir1中,无需手动移动。现在需要通过Python脚本实现这一效果,避免手动操作。
此前尝试直接修改arcname参数(如/{sub_path.name})或手动创建TarInfo对象均失败,出现目录结构异常、文件损坏等问题。
失败原因分析
- 错误的路径设置:直接为
dir1目录设置arcname="/dir1"时,跨平台(Windows创建、Linux解压)下TAR对绝对路径的处理可能出现不一致;若误遍历dir1的子项并设置arcname="/xxx",会导致子项与dir2/dir3同级,而非嵌套在/dir1下。 - 路径分隔符错误:使用Windows的反斜杠
\作为路径分隔符,会被TAR格式识别为文件名的一部分,导致异常目录。 - 手动TarInfo处理不当:未正确设置文件权限、大小等属性,或未正确读取文件内容写入TAR,导致解压时文件损坏。
解决方案
核心思路是将dir1下的所有内容,以/dir1/xxx的绝对路径格式添加到TAR中,确保解压时能直接映射到系统根目录的/dir1。具体步骤:
- 先添加
/dir1目录本身的条目; - 遍历
dir1下的所有子项,为每个子项设置以/dir1/为前缀的归档路径。
完整代码示例
from pathlib import Path import tarfile # 配置路径 tar_file_path = Path("my_tar.tar") unmod_path = Path("/path/to/dir2_dir3_parent") # 包含dir2、dir3的父目录 mod_path = Path("/path/to/dir1_parent") # 包含dir1的父目录 with tarfile.open(tar_file_path, "w", format=tarfile.GNU_FORMAT) as tfh: # 添加dir2和dir3,保持原有相对路径结构 for sub_path in unmod_path.iterdir(): tfh.add(sub_path, arcname=sub_path.name) # 处理dir1,映射为绝对路径/dir1 dir1_path = mod_path / "dir1" # 先添加/dir1目录本身的条目(确保解压时自动创建目录) dir1_tarinfo = tfh.gettarinfo(dir1_path, arcname="/dir1") tfh.addfile(dir1_tarinfo) # 遍历dir1下的所有子项,设置绝对路径归档名 for item in dir1_path.rglob("*"): # 计算子项相对于dir1的路径 rel_path = item.relative_to(dir1_path) # 构建绝对路径格式的归档名 arcname = f"/dir1/{rel_path}" tfh.add(item, arcname=arcname)
验证方法
在Linux系统上,使用以下命令查看TAR结构:
tar -tvf my_tar.tar
应能看到类似以下的输出,确认dir1下的内容均以/dir1/为前缀:
drwxr-xr-x user/group 0 YYYY-MM-DD HH:MM /dir1/ drwxr-xr-x user/group 0 YYYY-MM-DD HH:MM /dir1/sub-dir1/ -rw-r--r-- user/group XXX YYYY-MM-DD HH:MM /dir1/sub-dir1/file1 drwxr-xr-x user/group 0 YYYY-MM-DD HH:MM /dir1/sub-dir2/ -rw-r--r-- user/group XXX YYYY-MM-DD HH:MM /dir1/sub-dir2/file3 -rw-r--r-- user/group XXX YYYY-MM-DD HH:MM /dir1/file4 drwxr-xr-x user/group 0 YYYY-MM-DD HH:MM dir2/ -rw-r--r-- user/group XXX YYYY-MM-DD HH:MM dir2/file5 drwxr-xr-x user/group 0 YYYY-MM-DD HH:MM dir3/ -rw-r--r-- user/group XXX YYYY-MM-DD HH:MM dir3/file6 -rw-r--r-- user/group XXX YYYY-MM-DD HH:MM dir3/file7
解压时使用--absolute-names参数即可将/dir1下的内容直接放到系统根目录:
tar xf my_tar.tar --absolute-names
内容的提问来源于stack exchange,提问作者Angrod
相关产品推荐
相关产品推荐

