2009-02-25 8 views
16

Parece que esto no sería determinante, ¿o hay alguna manera de hacerlo de manera confiable?¿Hay una manera segura de ejecutar un diff en dos archivos comprimidos zip?

+1

¿De qué quieres una diferencia? La lista del archivo (FileA existe en uno pero no en el otro). El contenido de los archivos (FileB en el primer zip tiene estas modificaciones en comparación con el FileB en el segundo zip). ¿O todo lo anterior? La respuesta de eduffy puede funcionar (en Linux) si no te importan los contenidos. – JMD

+0

Además, ¿qué plataforma? Windows, Linux, otros? – JMD

+0

Si simplemente te importa si los archivos comprimidos son iguales, ¿por qué no comparar hashes? – EBGreen

Respuesta

7

Confiable: descomprimir ambos, diff.

No tengo idea si esa respuesta es suficiente para su uso, pero funciona.

+0

Estoy buscando evitar abrir, expandir y diferir, podría ser más costoso. – ApplePieIsGood

+0

Desafortunadamente, es la única manera confiable de hacerlo. – Powerlord

+1

@Powerlord: ¿por curiosidad la respuesta de eduffy no es confiable? ¿O solo después de tu comentario? – orangepips

29

Si está usando gzip, puede hacer algo como esto:

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

Bueno, necesito hacer esto programáticamente, y no estoy corriendo en un entorno Unix (desafortunadamente). – ApplePieIsGood

+5

¿cómo es que la solución en esta respuesta no está "programáticamente" resolviendo su problema? – hop

+6

Esto es bueno saberlo (nunca supe que podía canalizar dos secuencias de programas a otro programa sin hacer archivos temporales). Sin embargo, estaba confundido y tropezando con errores, hasta que me di cuenta de que ** no puede haber un espacio entre los < y el padre. ** –

1

Beyond compare tiene ningún problema con esto.

+0

Me pregunto si lo expanden detrás de las escenas y dif? Esa es la cuestión, es difícil decir con una aplicación lo que hace. – ApplePieIsGood

+0

Estoy bastante seguro de que se expanden detrás de escena. Deben poder mostrar una diferencia lado a lado de dos archivos de los archivos zip. –

+0

Es propietario, entonces, ¿quién sabe lo que hace? –

12

Bueno, me imagino que zdiff te serviría de algo.

+0

el enlace va a un sitio llamado 'Cómo redirigir la salida de comando a un archivo', por favor tenga la amabilidad de actualizar el enlace –

0

WinMerge (sólo Windows) tiene un montón de features y uno de ellos es:

  • soporte de archivos Archivo usando 7-Zip
5

En general, no se puede evitar la descompresión y luego comparando Los diferentes compresores darán como resultado diferentes flujos de bytes DEFLATED, que cuando INFLATEd resultan en el mismo texto original. No se puede simplemente comparar los datos DEFLATEDD, uno con otro. Eso fallará en algunos casos.

Pero en un escenario ZIP, hay un CRC32 calculado y almacenado para cada entrada. Por lo tanto, si desea verificar los archivos, simplemente puede comparar el CRC32 almacenado asociado a cada flujo DEFLATEd, con las advertencias sobre las propiedades de exclusividad del hash CRC32. Puede ajustarse a sus necesidades para comparar FileName y CRC.

Necesitará una biblioteca ZIP que lea los archivos zip y los exponga como propiedades en el objeto "ZipEntry". DotNetZip hará eso para las aplicaciones .NET.

2

Esto no es particularmente elegante, pero puede usar la aplicación FileMerge que viene con las herramientas de desarrollador Mac OS X para comparar los contenidos de los archivos zip utilizando un filtro personalizado.

crear un script ~/bin/zip_filemerge_filter.bash con contenidos:

#!/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 $? 

Haga el script ejecutable (chmod +x ~/bin/zip_filemerge_filter.bash).

Abra FileMerge, abra las Preferencias, y vaya a la pestaña "Filtros". Agregue un elemento a la lista con: Extensión: "zip", Filtro: "~/bin/zip_filemerge_filter.bash $ (FILE)", Pantalla: Filtrado, Aplicar *: No. (También he agregado el archivador para. jar y .war archivos)

A continuación, utilice FileMerge (o la línea de comandos "opendiff" envoltorio) para comparar dos archivos .zip.

Esto no le permitirá modificar el contenido de los archivos en los archivos zip, pero le permitirá ver rápidamente qué archivos aparecen en un solo archivo y qué archivos existen en ambos pero tienen diferente contenido (es decir, diferente tamaño y/o suma de comprobación).

1

En realidad, gzip y bzip2 vienen con herramientas dedicadas para hacerlo.

con gzip:

$ zdiff file1.gz file2.gz 

Con bzip2:

$ bzdiff file1.bz2 file2.bz2 

Pero hay que tener en cuenta que para archivos muy grandes, es posible que tenga problemas de memoria (que originalmente vinieron aquí para obtener información sobre cómo para resolverlos, entonces todavía no tengo la respuesta).

0

He encontrado alivio con este sencillo script en Perl: diffzips.pl

Se forma recursiva Diffs cada archivo zip dentro de la postal original, que es especialmente útil para los diferentes formatos de paquetes de Java: Tarro, la guerra y el oído.

zipcmp utiliza un enfoque más simple y no se repite en las cremalleras archivadas.

3

zipcmp compara los archivos zip zip1 y zip2 y comprueba si contienen los mismos archivos, comparando sus nombres, tamaños sin comprimir y CRC. La orden del archivo y las diferencias de tamaño comprimido se ignoran.

sudo apt-get install zipcmp

+0

¿Podría explicarme la salida devuelta ejecutando' zipcmp' Obtuve una línea de entrada como '- 2380 d0c49aea c5-custom-product-5.2.0/wso2/runtime2/bin/bootstrap/logging.properties'. Sé que '-' indica el archivo zip relavante, pero lo que se indica con' 2380' y 'd0c49aea'. Gracias –

+0

"2380" = zip de entrada; "d0c49aea" es md5 de entrada; "c5-custom-product-5.2.0/wso2/runtime2/bin/bootstrap/logging.properties" nombre de la entrada. Mire md5, la entrada puede tener el mismo tamaño pero diferente contenido – Wender

0

general utilizo un enfoque como @ mrabbit de comandos, pero corro 2 descomprimir y Diff la salida según sea necesario. Por ejemplo, necesito comparar 2 archivos WAR de Java.

$ 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) 

resultante de la producción de este modo:

--------   -------              --------   ------- 
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

Una solución pitón para archivos 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 

Uso como

diff(filename1, filename2) 

Se compara archivos línea por caso línea en la memoria y muestra cambios.

Cuestiones relacionadas