如何使用Linux的'tar'重命名放入tar归档文件中的文件

28

我想创建一个包含几个文件的 tar 压缩包,但是在压缩包中重命名这些文件。目前我的代码大致如下:

tar -czvf file1 /some/path/to/file2 file3 etc

但我想做类似这样的事情:

tar -czvf file1=file1 /some/path/to/file2=file2 file3=path/to/renamedFile3 etc=etc

当被提取到testDir目录中时,您将看到以下文件:

  • testDir/file1
  • testDir/file2
  • testDir/path/to/renamedFile3
  • testDir/etc

我该怎么做?

5个回答

34

您可以使用--transform修改文件名(以及其他内容)。例如,要创建一个磁带归档/tmp/foo.tar,并将文件/etc/profile/etc/bash.bashrc放入其中,同时将profile重命名为foo,可以执行以下操作:

tar --transform='flags=r;s|bar|foo|' -cf file.tar file1 file2 bar fubar /dir/*

以上的结果是将bar添加到file.tar中作为foo

r标志意味着只有对常规文件应用转换。有关更多信息,请参见GNU tar documentation

您可以多次使用--transform,例如:

tar --transform='flags=r;s|foo|bar|' --transform='flags=r;s|baz|woz|' -cf file.tar /some/dir/where/foo/is /some/dir/where/baz/is /other/stuff/* /dir/too

那绝对适用于重命名一个文件。如何重命名多个文件呢? - B T
多个转换和/或其中非常聪明的正则表达式。 - user2845360
你能给一个多个转换的例子吗?你只需要多次写--transform=...吗? - B T
1
你可能已经自己弄明白了这个问题,但我编辑了答案并给出了一个确切的例子。同时阅读文档,这样你就能更好地理解它是如何工作的(特别是转换标志的工作方式)。 - user2845360
1
如果搜索表达式是一个变量,而且它应该被视为字面量,该怎么办? - user877329
出于SEO的考虑,这也适用于提取,并且在解压具有双转义点(\\.)文件名的tar.gz时修复了我遇到的“无法打开:协议错误”问题:我能够使用 tar --transform='s|\\||g' -xzf archive.tar.gz 清理它们(请注意,-xzf 必须在 -transform 之后)。 - Skippy le Grand Gourou

7
使用--transform,无需先创建临时目录testDir。为了在存档文件中将所有内容的前缀改为testDir/,请匹配开头锚点^:
tar --transform "s|file3|path/to/renamedFile3|" \
    --transform "flags=r;s|^|testDir/|" \
    -czvf my_archive.tgz file1 /some/path/to/file2 file3 etc
r 标志对于在归档文件中保留任何符号链接目标(也匹配 ^)非常关键,以防止转换出现故障。

5
我们可以参考命令行工具"tar",使用"-O"选项最为合适,因为文件可以被写入标准输出。
-O      (x, t modes only) In extract (-x) mode, files will be written to
         standard out rather than being extracted to disk.  In list (-t)
         mode, the file listing will be written to stderr rather than the
         usual stdout.

以下是示例:

# 1. without -O
tar xzf 20170511162930.db.tar.gz
# result: 20170511162930.db

# 2. with -O
tar xzf 20170511162930.db.tar.gz -O > latest.db
# result: latest.db

这仅供提取使用。 - David Given

0

在我找不到满意的解决方案之后,我刚刚编写了tarlogs.py。它允许您为tar条目指定任意名称。每个tar条目由一个(或多个)常规(或gzipped)输入构成。您还可以添加目录,就像使用常规tar一样进行递归。所以在您的情况下,

tarlogs.py -o file1 -i /some/path/to/file2 -o file2 -i file3 -o path/to/renamedFile3 -o /etc >output.tar

(-o没有-i输入时,只需将输出路径用作输入路径,无需重命名)


0
这个问题已经存在一段时间了,但对于任何正在寻找另一个合适解决方案的人来说:
我创建了原始GNU tar实用程序的分支,并增加了文件名映射的额外支持。
使用示例:
> touch myfile.txt
> tar cf file.tar ':myfile.txt:dir/inside/tar/newname.txt'
> tar tvf file.tar
  -rw-rw-r-- user/user      0  2022-02-12 14:27 dir/inside/tar/newname.txt

该功能通过在文件名前加上冒号(:)来触发,如上所示。第二个冒号用作源文件位置和存档内所需文件名之间的分隔符。

:[源文件]:[tar包内所需名称]

此功能与-T(从文件输入列表)标志兼容。

如何编译它

> git clone https://github.com/leso-kn/tar
> cd tar
> ./bootstrap
> ./configure
> make -j4
# Run it
> src/tar --version

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接