web-dev-qa-db-ja.com

2つのZip圧縮ファイルでdiffを実行する安全な方法はありますか?

これは決定論的なことではないようです、またはこれを確実に行う方法はありますか?

19
ApplePieIsGood

Gzipを使用している場合は、次のようなことができます。

# diff <(zcat file1.gz) <(zcat file2.gz)
35
eduffy

信頼性:両方を解凍します。

その答えがあなたの使用に十分であるかどうかはわかりませんが、それは機能します。

7

zipcmp ZipアーカイブZip1とZip2を比較し、それらに同じファイルが含まれているかどうかを確認し、名前、非圧縮サイズ、およびCRCを比較します。ファイルの順序と圧縮されたサイズの違いは無視されます。

Sudo apt-get install zipcmp

5
Wender

一般に、解凍してから比較することは避けられません。コンプレッサーが異なれば、DEFLATEdバイトストリームも異なり、INFLATEdの場合、元のテキストは同じになります。 DEFLATEdデータを単純に比較することはできません。場合によっては失敗します。

ただし、Zipシナリオでは、各エントリに対して計算および保存されたCRC32があります。したがって、ファイルをチェックする場合は、各DEFLATEdストリームに関連付けられた保存済みCRC32を、CRC32ハッシュの一意性プロパティに関する警告と簡単に比較できます。 FileNameとCRCを比較するニーズに合う場合があります。

Zipファイルを読み取り、それらを「ZipEntry」オブジェクトのプロパティとして公開するZipライブラリが必要になります。 DotNetZipは、.NETアプリに対してそれを行います。

5
Cheeso

これは特に洗練されているわけではありませんが、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つのアーカイブ内に表示されるファイルと、両方に存在するが内容が異なる(つまり、サイズやチェックサムが異なる)ファイルをすばやく確認できます。

2
mrabbitt

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行ずつ比較し、変更を表示します。

1
serv-inc

実際、gzipとbzip2には、そのための専用ツールが付属しています。

Gzipを使用する場合:

$ zdiff file1.gz file2.gz

Bzip2の場合:

$ bzdiff file1.bz2 file2.bz2

ただし、非常に大きなファイルの場合、メモリの問題が発生する可能性があることに注意してください(私はもともと、それらを解決する方法を見つけるためにここに来たので、まだ答えがありません)。

1
user48678

比較を超えて これには問題はありません。

1

WinMerge (Windowsのみ)にはたくさんの 機能 があり、そのうちの1つは次のとおりです。

  • 7-Zipを使用したアーカイブファイルのサポート
0
RuudKok

私は通常、@ 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/
...
...
0
slm

私はこの単純なPerlスクリプトで安心を見つけました: diffzips.pl

元のZip内のすべてのZipファイルを再帰的に差分します。これは、さまざまなJavaパッケージ形式:jar、war、ear)で特に役立ちます。

zipcmp より単純なアプローチを使用し、アーカイブされたzipに再帰しません。

0
Taavi Ilves

私は既存のツールの使用をあきらめ、自分に役立つ小さな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}"
0
Onno Benschop