zip文件中的文件而不提取它

时间:2016-02-23 15:17:48

标签: linux zip diff unzip

有没有办法在两个拉链中的两个文件上执行diff operetion而不提取它们?如果没有 - 任何其他解决方法来比较它们而不提取?

感谢。

10 个答案:

答案 0 :(得分:6)

unzip -l将列出zip文件的内容。然后,您可以按正常方式将其传递给diffhttps://askubuntu.com/questions/229447/how-do-i-diff-the-output-of-two-commands

例如,如果您有两个zip文件:

foo.zip
bar.zip

您可以运行diff -y <(unzip -l foo.zip) <(unzip -l bar.zip)对两个文件的内容进行并排差异化。

希望有所帮助!

答案 1 :(得分:6)

到目前为止,结合响应,以下bash函数将比较zip文件中的文件列表。列表包括详细输出(unzip -v),因此可以比较校验和。输出按文件名(sort -k8)排序,以允许并排比较和展开的diff输出(W200),因此文件名在并排视图中可见。

function zipdiff() { diff -W200 -y <(unzip -vql $1 | sort -k8) <(unzip -vql $2 | sort -k8); }

这可以添加到您要在任何控制台中使用的~/.bashrc文件中。它可以与zipdiff a.zip b.zip一起使用。将输出管道设置为较小或重定向到文件对于大型zip文件很有用。

答案 2 :(得分:4)

如果你想要diff两个文件(如看到区别),你必须提取它们 - 即使只是为了记忆!

为了看到两个拉链中的两个文件的差异你可以做这样的事情(没有错误检查或任何错误):

# define a little bash function
function zipdiff () { diff -u <(unzip -p $1 $2) <(unzip -p $3 $4); }

# test it: create a.zip and b.zip, each with a different file.txt
echo hello >file.txt; zip a.zip file.txt
echo world >file.txt; zip b.zip file.txt

zipdiff a.zip file.txt b.zip file.txt
--- /dev/fd/63  2016-02-23 18:18:09.000000000 +0100
+++ /dev/fd/62  2016-02-23 18:18:09.000000000 +0100
@@ -1 +1 @@
-hello
+world

注意:unzip -p将文件提取到 p ipe(标准输出)。

如果您只想知道文件是否不同,可以使用

检查其校验和
unzip -v -l zipfile [file_to_inspect]

注意:-v表示详细和-l列表内容)

unzip -v -l a.zip 
Archive:  a.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
       6  Stored        6   0% 2016-02-23 18:23 363a3020  file.txt
--------          -------  ---                            -------
       6                6   0%                            1 file

unzip -v -l b.zip 
Archive:  b.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
       6  Stored        6   0% 2016-02-23 18:23 dd3861a8  file.txt
--------          -------  ---                            -------
       6                6   0%                            1 file 

在上面的示例中,您可以看到校验和(CRC-32)不同。

您可能也对此项目感兴趣: https://github.com/nhnb/zipdiff

答案 3 :(得分:1)

仅压缩文件内容

我一直在寻找一种方法来比较zip文件中存储的文件的内容,而不是其他元数据。请考虑以下内容:

/beta

从概念上讲,这没有任何意义;我在相同的输入上运行了相同的命令,并得到2个不同的输出!区别在于元数据,它存储文件添加的日期!

$ echo foo > foo.txt
$ zip now.zip foo.txt
  adding: foo.txt (stored 0%)
$ zip later.zip foo.txt
  adding: foo.txt (stored 0%)
$ diff now.zip later.zip 
Binary files now.zip and later.zip differ

注意:为清楚起见,我在此处手动将第二个文件的时间从$ unzip -v now.zip Archive: now.zip Length Method Size Cmpr Date Time CRC-32 Name -------- ------ ------- ---- ---------- ----- -------- ---- 4 Stored 4 0% 04-08-2020 23:27 7e3265a8 foo.txt -------- ------- --- ------- 4 4 0% 1 file $ unzip -v later.zip Archive: later.zip Length Method Size Cmpr Date Time CRC-32 Name -------- ------ ------- ---- ---------- ----- -------- ---- 4 Stored 4 0% 04-08-2020 23:28 7e3265a8 foo.txt -------- ------- --- ------- 4 4 0% 1 file 修改为23:27。即使文件中的字段未存储在命令的输出中,该字段本身也会存储秒的值(在我的情况下,该值有所不同-二进制差异仍然会失败)。

因此,仅比较文件,我们必须忽略日期字段。 23:28将为我们提供更好的摘要:

unzip -vqq

因此,让我们掩盖字段(我们不在乎日期或压缩指标)并对文件进行排序:

$ unzip -vqq now.zip
       4  Stored        4   0% 04-08-2020 23:27 7e3265a8  foo.txt

TL; DR

比较2个zip文件($ unzip -vqq now.zip | awk '{$2=""; $3=""; $4=""; $5=""; $6=""; print}' | sort -k3 4 7e3265a8 foo.txt a.zip)的命令是

b.zip

答案 4 :(得分:1)

通过对zipcmp的输出进行后处理,您可以递归遍历各个档案,以获得它们之间差异的更详细的摘要。

#!/bin/bash

# process zipcmp's output to do true diffs of archive contents
# 1. grep removes the '+++' and '---' from zipcmp's output
# 2. awk prints the final column of output
# 3. sort | uniq to dedupe
for badfile in $(zipcmp ${1?No first zip} ${2?No second zip} \
    | grep -Ev '^[+-]{3}' \
    | awk '{print $NF}' \
    | sort | uniq);
do
    echo "diffing $badfile"
    diff <(unzip -p $1 $badfile) <(unzip -p $2 $badfile) ;
done;

答案 5 :(得分:0)

如果您只需检查文件是否相等,您可以比较CRC32校验和,它存储在存档本地标题字段/中央目录中。

答案 6 :(得分:0)

我希望以可读取的格式在zip文件中的实际差异。这是我为此目的编写的bash函数,它使用git。如果您已经将git用作正常工作流程的一部分,并且可以读取git diff,那么这将是一个不错的UX。

# usage: zipdiff before.zip after.zip
function zipdiff {
  current=$(pwd)
  before="$current/$1"
  after="$current/$2"
  tempdir=$(mktemp -d)
  cd $tempdir
  git init &> /dev/null
  unzip -qq $before *
  git add . &> /dev/null
  git commit -m "before" &> /dev/null
  rm -rf $tempdir/*  
  yes | unzip -qq $after * &> /dev/null
  git add .
  git diff --cached
  cd $current
  rm -rf $tempdir
}

答案 7 :(得分:0)

开源库Zip-Ada中的 comp_zip 工具(可用herehere)执行比较而不提取:内容,a.zip文件丢失在b.zip和两者的完整性检查中。

答案 8 :(得分:0)

诸如https://www.diffnow.com/compare-files之类的网络工具提供了相当不错的视觉信息,其中zip文件已更改:

enter image description here

这对于不太大的zip文件非常方便,而无需安装任何内容。这不仅适用于Linux,而且适用于其他操作系统,包括Windows和Mac。

其他答案中讨论的工具显然提供了更高级的选项,并且对于较大的zip文件而言可能更快。

答案 9 :(得分:0)

存在一些命令行工具:

  1. diffzips.pl 用 Perl 编写。
  2. zipdiff 用 Ja​​va 编写。
  3. zipdiff 端口到上一个的 .NET。
  4. zipcmp 用 C 语言编写,来自 libzip 库
  5. zcmpzdiff 来自 gzip,可用于 zip 文件。

我很高兴使用 diffzips.pl 来比较 epub 文件的内容。 diffzips.pl 还具有递归的优点,可以比较父 zip 中的 zip 文件。