有没有办法在不解压缩的情况下,在两个 zip 文件中对两个文件执行 diff 操作?如果不行 - 是否有其他方法可以在不解压缩的情况下比较它们?
谢谢。
综合目前的回应,以下bash函数将比较zip文件中的文件列表。列表包括详细输出(unzip -v
),因此可以比较校验和。输出按文件名排序(sort -k8
),以允许并排比较,并展开差异输出(W200
),以便在并排视图中看到文件名。
function zipdiff() { diff -W200 -y <(unzip -vql "$1" | sort -k8) <(unzip -vql "$2" | sort -k8); }
您可以将此内容添加到~/.bashrc
文件中,以便在任何控制台中使用。它可与zipdiff a.zip b.zip
一起使用。将输出导入less
或重定向到文件对于大型zip文件很有帮助。
--suppress-common-lines
可以使它变得更好。 - Steve Kehletfunction zipcdiff() { A='{printf("%8sB %s %s\n",$1,$7,$8)}'; diff <(unzip -vqql "$1" | awk "$A" | sort -k3) <(unzip -vqql "$2" | awk "$A" | sort -k3); }
。当内容相等时, 输出为空。用于检查确定性构建的有用工具。 - geekleyunzip -l
命令将列出 zip 文件的内容。然后,您可以像此处提到的那样以普通方式将其传递给 diff
:https://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)
来比较两个文件的内容。希望能对你有所帮助!--suppress-common-lines
标志添加到命令中可以只显示不同的行,效果非常好:diff -y <(unzip -l foo.zip) <(unzip -l bar.zip) --suppress-common-lines
- Kostas Minaidisfunction zipdiff() { diff -y <(unzip -l $1) <(unzip -l $2) --suppress-common-lines; }
这个函数,它完美地完成了我想做的事情。 - Velizar Hristov我想以易读的格式获取压缩文件中文件间的实际差异。以下是我为此目的编写的一个Bash函数,它利用了git。如果您已经将git作为正常工作流程的一部分使用并可以读取git diffs,则具有良好的用户体验。
# 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"
}
对比两个zip文件(a.zip
和b.zip
)的命令为:
diff \
<(unzip -vqq a.zip | awk '{$2=""; $3=""; $4=""; $5=""; $6=""; print}' | sort -k3 -f) \
<(unzip -vqq b.zip | awk '{$2=""; $3=""; $4=""; $5=""; $6=""; print}' | sort -k3 -f)
我正在寻找一种比较zip文件中存储的文件内容而非其他元数据的方法。请考虑以下情况:
$ 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
从概念上讲,这是没有意义的;我在相同的输入上运行了相同的命令,却得到了2个不同的输出!这种差异是由元数据引起的,元数据存储了文件添加日期!
$ 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
因此,让我们屏蔽字段(我们不关心日期或压缩指标),并对文件进行排序:
$ unzip -vqq now.zip | awk '{$2=""; $3=""; $4=""; $5=""; $6=""; print}' | sort -k3 -f
4 7e3265a8 foo.txt
如果你想比较两个文件(即查看它们的不同之处),你必须将它们提取出来——即使只是到内存中!
为了查看两个zip文件中的两个文件的差异,你可以像这样操作(没有错误检查或任何其他操作):
# 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
命令会将文件提取到管道(stdout)中。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
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;
如果您只需要检查文件是否相等,则可以比较存储在存档本地头字段/中央目录中的CRC32校验和。
像https://www.diffnow.com/compare-files这样的网络工具提供了非常好的视觉信息,可以显示压缩文件中哪些文件已更改:
这对于不太大的zip文件非常方便,而且无需安装任何东西。这不仅适用于Linux,还适用于其他操作系统,包括Windows和Mac。
其他答案中讨论的工具显然提供了更高级的选项,并且对于较大的zip文件可能更快。
sha512 文件名1
和sha512 文件名2
并查看输出是否相同。 - vishal