Подтвердить что ты не робот

Есть ли безопасный способ запуска diff на два ZIP файла?

Кажется, это не будет детерминированной вещью, или есть способ сделать это надежно?

4b9b3361

Ответ 1

Если вы используете gzip, вы можете сделать что-то вроде этого:

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

Ответ 2

Ну, я полагаю, zdiff будет вам полезен.

Ответ 3

Надежность: разархивируйте оба параметра.

Я понятия не имею, что этот ответ достаточно хорош для вашего использования, но он работает.

Ответ 4

В общем, вы не можете избежать распаковки и сравнения. Различные компрессоры приведут к различным потокам байтов DEFLATEd, которые, когда INFLATEd приведут к тому же оригинальному тексту. Вы не можете просто сравнивать данные DEFLATEd друг с другом. В некоторых случаях это будет FAIL.

Но в сценарии ZIP есть CRC32, рассчитанный и сохраненный для каждой записи. Поэтому, если вы хотите проверить файлы, вы можете просто сравнить сохраненный CRC32, связанный с каждым потоком DEFLATEd, с оговорками о свойствах уникальности хэша CRC32. Он может соответствовать вашим потребностям для сравнения FileName и CRC.

Вам понадобится ZIP-библиотека, которая читает zip файлы и выставляет эти объекты как свойства объекта ZipEntry. DotNetZip сделает это для приложений .NET.

Ответ 5

zipcmp сравнивает zip-архивы zip1 и zip2 и проверяет, содержат ли они одни и те же файлы, сравнивая их имена, несжатые размеры и CRC. Разделения файла и сжатого размера игнорируются.

sudo apt-get install zipcmp

Ответ 6

Это не особенно элегантно, но вы можете использовать приложение FileMerge, которое поставляется с инструментами разработчика Mac OS X, для сравнения содержимого zip файлов с использованием настраиваемого фильтра.

Создайте script ~/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 $?

Сделайте исполняемый файл script (chmod +x ~/bin/zip_filemerge_filter.bash).

Откройте FileMerge, откройте "Настройки" и перейдите на вкладку "Фильтры". Добавьте элемент в список: Расширение: "zip", Filter: "~/bin/zip_filemerge_filter.bash $(FILE)", Display: Filtered, Apply *: Нет (я также добавил файл для файлов .jar и .war).

Затем используйте FileMerge (или командную строку "opendiff" wrapper), чтобы сравнить два .zip файла.

Это не позволит вам различать содержимое файлов в zip-архивах, но позволит вам быстро увидеть, какие файлы появляются в одном только архиве и какие файлы существуют в обоих, но имеют разный контент (т.е. разные размеры и/или контрольная сумма).

Ответ 8

На самом деле gzip и bzip2 имеют специальные инструменты для этого.

С gzip:

$ zdiff file1.gz file2.gz

С bzip2:

$ bzdiff file1.bz2 file2.bz2

Но имейте в виду, что для очень больших файлов вы можете столкнуться с проблемами памяти (я изначально пришел сюда, чтобы узнать, как их решить, поэтому у меня пока нет ответа).

Ответ 9

Решение 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)

Он сравнивает файлы по очереди в памяти и показывает изменения.

Ответ 10

WinMerge (только окна) имеет множество функций, и один из них:

  • Поддержка архивных файлов с помощью 7-Zip

Ответ 11

Я нашел рельеф с этим простым Perl script: diffzips.pl

Он рекурсивно разграничивает каждый zip файл внутри исходного почтового индекса, что особенно полезно для разных форматов пакетов Java: jar, war и ear.

zipcmp использует более простой подход и не перезаписывает архивные ZIP файлы.

Ответ 12

Обычно я использую такой подход, как @mrabbit, но запускаю 2 разархивированные команды и разграничиваю вывод по мере необходимости. Например, мне нужно сравнить 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/
...
...