これは決定論的なことではないようです、またはこれを確実に行う方法はありますか?
Gzipを使用している場合は、次のようなことができます。
# diff <(zcat file1.gz) <(zcat file2.gz)
信頼性:両方を解凍します。
その答えがあなたの使用に十分であるかどうかはわかりませんが、それは機能します。
zipcmp ZipアーカイブZip1とZip2を比較し、それらに同じファイルが含まれているかどうかを確認し、名前、非圧縮サイズ、およびCRCを比較します。ファイルの順序と圧縮されたサイズの違いは無視されます。
Sudo apt-get install zipcmp
一般に、解凍してから比較することは避けられません。コンプレッサーが異なれば、DEFLATEdバイトストリームも異なり、INFLATEdの場合、元のテキストは同じになります。 DEFLATEdデータを単純に比較することはできません。場合によっては失敗します。
ただし、Zipシナリオでは、各エントリに対して計算および保存されたCRC32があります。したがって、ファイルをチェックする場合は、各DEFLATEdストリームに関連付けられた保存済みCRC32を、CRC32ハッシュの一意性プロパティに関する警告と簡単に比較できます。 FileNameとCRCを比較するニーズに合う場合があります。
Zipファイルを読み取り、それらを「ZipEntry」オブジェクトのプロパティとして公開するZipライブラリが必要になります。 DotNetZipは、.NETアプリに対してそれを行います。
これは特に洗練されているわけではありませんが、Mac OS X開発ツールに付属のFileMergeアプリケーションを使用して、カスタムフィルターを使用してZipファイルの内容を比較できます。
スクリプトを作成する~/bin/Zip_filemerge_filter.bash
内容付き:
#!/bin/bash
##
# List the size, CR-32 checksum, and file path of each file in a Zip archive,
# sorted in order by file path.
##
unzip -v -l "${1}" | cut -c 1-9,59-,49-57 | sort -k3
exit $?
スクリプトを実行可能にします(chmod +x ~/bin/Zip_filemerge_filter.bash
)。
FileMergeを開き、[設定]を開いて、[フィルター]タブに移動します。次の項目を使用してリストにアイテムを追加します:Extension: "Zip"、Filter: "〜/ bin/Zip_filemerge_filter.bash $(FILE)"、Display:Filtered、Apply *:No。(。jarのファイラーも追加しましたおよび.warファイル。)
次に、FileMerge(またはコマンドラインの「opendiff」ラッパー)を使用して、2つの.Zipファイルを比較します。
これにより、Zipアーカイブ内のファイルの内容を比較することはできませんが、1つのアーカイブ内に表示されるファイルと、両方に存在するが内容が異なる(つまり、サイズやチェックサムが異なる)ファイルをすばやく確認できます。
python Zipファイルのソリューション:
import difflib
import zipfile
def diff(filename1, filename2):
differs = False
z1 = zipfile.ZipFile(open(filename1))
z2 = zipfile.ZipFile(open(filename2))
if len(z1.infolist()) != len(z2.infolist()):
print "number of archive elements differ: {} in {} vs {} in {}".format(
len(z1.infolist()), z1.filename, len(z2.infolist()), z2.filename)
return 1
for zipentry in z1.infolist():
if zipentry.filename not in z2.namelist():
print "no file named {} found in {}".format(zipentry.filename,
z2.filename)
differs = True
else:
diff = difflib.ndiff(z1.open(zipentry.filename),
z2.open(zipentry.filename))
delta = ''.join(x[2:] for x in diff
if x.startswith('- ') or x.startswith('+ '))
if delta:
differs = True
print "content for {} differs:\n{}".format(
zipentry.filename, delta)
if not differs:
print "all files are the same"
return 0
return 1
使用
diff(filename1, filename2)
メモリ内のファイルを1行ずつ比較し、変更を表示します。
実際、gzipとbzip2には、そのための専用ツールが付属しています。
Gzipを使用する場合:
$ zdiff file1.gz file2.gz
Bzip2の場合:
$ bzdiff file1.bz2 file2.bz2
ただし、非常に大きなファイルの場合、メモリの問題が発生する可能性があることに注意してください(私はもともと、それらを解決する方法を見つけるためにここに来たので、まだ答えがありません)。
比較を超えて これには問題はありません。
私は通常、@ mrabbitのようなアプローチを使用しますが、2つのunzipコマンドを実行し、必要に応じて出力を比較します。たとえば、2つのJava WARファイルを比較する必要があります。
$ sdiff --width 160 \
<(unzip -l -v my_num1.war | cut -c 1-9,59-,49-57 | sort -k3) \
<(unzip -l -v my_num2.war | cut -c 1-9,59-,49-57 | sort -k3)
次のような出力になります。
-------- ------- -------- -------
Archive: Archive:
-------- -------- ---- -------- -------- ----
48619281 130 files | 51043693 130 files
1116 060ccc56 index.jsp 1116 060ccc56 index.jsp
0 00000000 META-INF/ 0 00000000 META-INF/
155 b50f41aa META-INF/MANIFEST.MF | 155 701f1623 META-INF/MANIFEST.MF
Length CRC-32 Name Length CRC-32 Name
1179 b42096f1 version.jsp 1179 b42096f1 version.jsp
0 00000000 WEB-INF/ 0 00000000 WEB-INF/
0 00000000 WEB-INF/classes/ 0 00000000 WEB-INF/classes/
0 00000000 WEB-INF/classes/com/ 0 00000000 WEB-INF/classes/com/
...
...
私はこの単純なPerlスクリプトで安心を見つけました: diffzips.pl
元のZip内のすべてのZipファイルを再帰的に差分します。これは、さまざまなJavaパッケージ形式:jar、war、ear)で特に役立ちます。
zipcmp より単純なアプローチを使用し、アーカイブされたzipに再帰しません。
私は既存のツールの使用をあきらめ、自分に役立つ小さなbashスクリプトを作成しました。
#!/bin/bash
# Author: Onno Benschop, [email protected]
# Note: This requires enough space for both archives to be extracted in the tempdir
if [ $# -ne 2 ] ; then
echo Usage: $(basename "$0") Zip1 Zip2
exit
fi
# Make temporary directories
archive_1=$(mktemp -d)
archive_2=$(mktemp -d)
# Unzip the archives
unzip -qqd"${archive_1}" "$1"
unzip -qqd"${archive_2}" "$2"
# Compare them
diff -r "${archive_1}" "${archive_2}"
# Remove the temporary directories
rm -rf "${archive_1}" "${archive_2}"