2009-02-25 2 views
16

Кажется, это не было детерминированной вещью, или есть способ сделать это надежно?Есть ли безопасный способ запуска diff на два ZIP-файла?

+1

Что вы хотите изменить? Список файлов (FileA существует в одном, но не другом). Содержимое файлов (FileB в первом zip имеет эти изменения по сравнению с FileB во втором zip-файле). Или все, что выше? Ответ eduffy может работать (в Linux), если вы не заботитесь о содержимом. – JMD

+0

Кроме того, какая платформа? Windows, Linux, другие? – JMD

+0

Если вам все равно, если zipped-файлы совпадают, то почему бы не сравнить хэши? – EBGreen

ответ

7

Надежность: распаковать оба, разн.

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

+0

Я стараюсь избегать открытия и расширения, и это может быть дороже. – ApplePieIsGood

+0

К сожалению, это единственный надежный способ сделать это. – Powerlord

+1

@Powerlord: из любопытства ответ эдди ненадежен? Или чуть позже вашего комментария? – orangepips

29

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

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

Ну, мне нужно сделать это программно, и я не работаю в среде unix (к сожалению). – ApplePieIsGood

+5

Как решение в этом ответе не «программно» решает вашу проблему? – hop

+6

Это замечательно знать (я никогда не знал, что вы могли бы транслировать в две программные потоки в другую программу, не создавая временных файлов.) Я был смущен и запутался в ошибках, хотя до тех пор, пока не понял, что у вас не может быть пробела между < и paren. ** –

1

Beyond compare не имеет никаких проблем с этим.

+0

Интересно, расширяют ли они его за кулисами и diff? Это то, что трудно сказать с помощью приложения, что он делает. – ApplePieIsGood

+0

Я уверен, что они расширяются за кулисами. Они должны быть в состоянии показать бок о бок diff двух файлов из архивов zip. –

+0

Это собственность, поэтому кто знает, что она делает? –

12

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

+0

ссылка идет на сайт под названием «Как перенаправить вывод команды в файл», пожалуйста, будьте любезны, чтобы обновить ссылку –

0

WinMerge (только для Windows) имеет много features и один из них:

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

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

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

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

2

Это не особенно элегантно, но вы можете использовать приложение FileMerge, которое поставляется с инструментами разработчика Mac OS X, для сравнения содержимого 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, откройте «Настройки» и перейдите на вкладку «Фильтры». Добавьте элемент в список: Расширение: «zip», Filter: «~/bin/zip_filemerge_filter.bash $ (FILE)», Display: Filtered, Apply *: No. (Я также добавил фильтр для. jar и .war.)

Затем используйте FileMerge (или командную строку «opendiff» wrapper) для сравнения двух .zip-файлов.

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

1

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

С Gzip:

$ zdiff file1.gz file2.gz 

С bzip2:

$ bzdiff file1.bz2 file2.bz2 

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

0

Я нашел облегчение с помощью этого простого сценария Perl: diffzips.pl

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

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

3

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

Sudo APT-получить установку zipcmp

+0

Не могли бы вы объяснить мне результат, полученный при запуске 'zipcmp'. Я получил строку ввода, например' - 2380 d0c49aea c5-пользовательский продукт-5.2.0/WSO2/runtime2/бен/самозагрузки/logging.properties'. Я знаю, что '-' указывает на relavant zip-файл, но то, что указано' 2380' и 'd0c49aea'. Спасибо –

+0

"2380" = почтовый индекс; «d0c49aea» - md5 входа; «имя записи c5-custom-product-5.2.0/wso2/runtime2/bin/bootstrap/logging.properties». Посмотрите на md5, запись может быть того же размера, но другого контента – Wender

0

Я обычно используют такой подход, как @ 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/ 
... 
... 
1

питона решение для архивных файлов:

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) 

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

Смежные вопросы