转换tar存档的路径而不提取它


10

GNU tar(1)有一个名为的简洁选项--transform。从手册页:

--transform,--xform EXPRESSION
使用sed替换EXPRESSION来转换文件名

这样就可以在提取存档时动态转换路径名,以便您可以控制提取位置和方式。

我的问题是,是否有一种方法可以在原位执行类似的转换;即,没有提取档案?

[user@host]$ tar tf test.tar
./foo/blah  ./foo/bleh
[user@host]$ some_deep_magic 's/foo/bar/' test.tar
[user@host]$ tar tf test.tar
./bar/blah  ./bar/bleh

用例

我正在将tar归档文件分发给基本上毫无头绪的最终用户,并且希望将其提取到正确的路径中,而不会受到我的干扰。我试图避免提取存档,重命名目录和重新打包的简单解决方案,因为存档比较大。


为什么创建名称时不转换名称?
Jose Luis Martin

@JoseLuisMartin对。我的用例是存档已经存在,并且正如我所说,我希望避免解压缩,转换和重新打包。
Joseph R.

1
您可以修改该焦油物流没有实际它解压到硬盘:github.com/mafintosh/tar-stream#modifying-existing-tarballsperldoc.perl.org/5.10.1/Archive/Tar.html
vladr

Answers:


3

您可以使用archivemount或mountavfs挂载归档文件,然后重新创建它

archivemount tarfile.tar /mnt
cd /mnt
tar cf /tmp/tarfile.tar --transform 's/foo/bar/' .

在归档文件系统上执行写操作将对umount进行完全重写,因此对于大文件而言似乎不是一个好选择。

编辑

我不知道实现细节,但似乎我们正在将写入文件保存到文件系统步骤。

只需测试以解决问题,(在我的/ usr的tar上)

#!/bin/bash

# try to avoid slab cache issues 
cat /tmp/usr.tar > /dev/null

T="$(date +%s)"
tar xf /tmp/usr.tar
tar cf usr.tar usr --transform 's/usr/foo/'
T="$(($(date +%s)-T))"
echo "Tar/Untar seconds: ${T}"

T="$(date +%s)"
archivemount -o readonly -o nobackup /tmp/usr.tar /mnt
tar cf usr.tar /mnt  --transform 's/usr/foo/'
umount /mnt
T="$(($(date +%s)-T))"
echo "Archivemount seconds: ${T}"

T="$(date +%s)"
mountavfs
cd '/root/.avfs/tmp/usr.tar#'
tar cf /tmp/test/usr.tar   --transform 's/usr/foo/' .
T="$(($(date +%s)-T))"
echo "Avfs seconds: ${T}"

输出:

Tar/Untar seconds: 480
Archivemount seconds:  failure, a lot of read errors.
Avfs seconds: 217

因此,Avfs获胜!


1
+1有趣的新命令。但是这种方法与解压缩存档文件有何不同?我说的不是实现方面的,而是性能方面的。
Joseph R.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.