如何比较两个tarball的内容

myj*_*jpa 30 linux compression compare tar

我想告诉两个tarball文件在文件名和文件内容方面是否包含相同的文件,不包括日期,用户,组等元数据.

但是,有一些限制:首先,我无法控制在制作tar文件时是否包含元数据,实际上,tar文件总是包含元数据,因此直接对两个tar文件进行区分不起作用.其次,由于一些tar文件太大,以至于我无法将它们解压缩到临时目录中并逐个区分包含的文件.(我知道如果我可以将file1.tar解压缩到file1 /中,我可以通过在文件/中调用'tar -dvf file2.tar'来比较它们.但通常我甚至不能解压它们中的一个)

知道如何比较两个tar文件吗?如果可以在SHELL脚本中完成它会更好.或者,有没有办法获得每个子文件的校验和而不实际解压缩tarball?

谢谢,

nik*_*nik 11

你在控制这些tar文件的创建吗?
如果是这样,最好的技巧是创建MD5校验和并将其存储在存档本身的文件中.然后,当您想要比较两个文件时,您只需提取此校验和文件并进行比较.


如果您只能提取一个tar文件,则可以使用--diff选项tar查找与其他tar文件内容的差异.


还有一招原油,如果你是罚款只是一个文件名及其大小的比较.
请记住,这并不能保证其他文件是一样的!

执行a tar tvf列出每个文件的内容并将输出存储在两个不同的文件中.然后,切除除文件名和大小列之外的所有内容.最好也对两个文件进行排序.然后,只需在两个列表之间进行文件差异.

请记住,最后一个方案并不真正做校验和.

示例tar和输出(在此示例中,所有文件都为零大小).

$ tar tvfj pack1.tar.bz2
drwxr-xr-x user/group 0 2009-06-23 10:29:51 dir1/
-rw-r--r-- user/group 0 2009-06-23 10:29:50 dir1/file1
-rw-r--r-- user/group 0 2009-06-23 10:29:51 dir1/file2
drwxr-xr-x user/group 0 2009-06-23 10:29:59 dir2/
-rw-r--r-- user/group 0 2009-06-23 10:29:57 dir2/file1
-rw-r--r-- user/group 0 2009-06-23 10:29:59 dir2/file3
drwxr-xr-x user/group 0 2009-06-23 10:29:45 dir3/
Run Code Online (Sandbox Code Playgroud)

生成已排序的名称/大小列表的命令

$ tar tvfj pack1.tar.bz2 | awk '{printf "%10s %s\n",$3,$6}' | sort -k 2
0 dir1/
0 dir1/file1
0 dir1/file2
0 dir2/
0 dir2/file1
0 dir2/file3
0 dir3/
Run Code Online (Sandbox Code Playgroud)

你可以采取两个这样的排序列表并区分它们.
如果适合您,您还可以使用日期和时间列.

  • 你也可以将两个这样的命令的输出直接传递给diff工具,例如:meld <(tar tvfj ... | awk ...)<(tar tvfj ... | awk ...) (2认同)

lin*_*ild 11

还可以尝试使用pkgdiff来查看包之间的差异(检测添加/删除/重命名的文件和更改的内容,如果没有更改则存在零代码):

pkgdiff PKG-0.tgz PKG-1.tgz
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在此输入图像描述


Gre*_*ith 7

tarsum几乎就是你所需要的。取出它的输出,通过 sort 运行它以获得相同的排序,然后将两者与 diff 进行比较。这应该会让你有一个基本的实现,通过修改 Python 代码来完成整个工作,将这些步骤拉到主程序中是很容易的。

  • 在两个 tarball 之间进行比较需要创建一对 (file,md5) 条目列表并计算两个列表之间的差异。用直接的 shell 编写真的很痛苦,而用 Python 或 Perl 编写却很简单。这就是为什么你不太可能在这里首先给出一个直接的 shell 答案——这正是激发创建这些语言的那种问题。如果您不想完全疯狂地写这个东西,那么从 tarsum(或 tardiff Perl 代码)开始并根据您的特定需求对其进行定制比使用直接 shell 好得多。 (2认同)

Arr*_*erg 7

我意识到这是一个迟到的回复,但我在尝试实现同样的事情时遇到了这个问题.我实现的解决方案将tar输出到stdout,并将其管道到您选择的任何哈希:

tar -xOzf archive.tar.gz | sort | sha1sum
Run Code Online (Sandbox Code Playgroud)

请注意,参数的顺序很重要; 特别是O哪些信号使用stdout.

  • `tar -x0zf` 会转储存档的全部内容,然后 `sort` 将所有行按顺序排列,这并没有解决“存档中文件的顺序”问题,而是通过混合添加了一个新问题线。档案可能因换行而不同,并且不会被捕获。取而代之的是获取文件列表,省略目录,对列表进行排序,然后告诉 `tar` 按照该顺序提取: `tar -xOzf archive.tar.gz \`tar -tzf archive.tar.gz | sed '/\/$/d' | 排序\` | sha1sum` (3认同)
  • 在管道中使用“排序”实际上需要保存所有解压缩的内容存档内容*内存*。如果存档太大以至于 OP 无法将它们写入*磁盘*,那么这肯定会失败。无论如何,正如其他评论所指出的那样,这对机器来说意味着更多的工作。我使用了 @GregSmith 接受的答案中的 tarsum ,我对此非常满意。 (2认同)

小智 6

这是我的变体,它也在检查unix权限:

仅当文件名少于200个字符时才有效。

diff <(tar -tvf 1.tar | awk '{printf "%10s %200s %10s\n",$3,$6,$1}'|sort -k2) <(tar -tvf 2.tar|awk '{printf "%10s %200s %10s\n",$3,$6,$1}'|sort -k2)
Run Code Online (Sandbox Code Playgroud)