
Tengo tres archivos binarios (volcados de memoria). Llámalos file1
, file2
, file3
. Estoy intentando depurar algún software y estoy activando un interruptor.
file1
= apagarfile2
= encenderfile3
= apagar
Necesito saber qué bytes cambiaron entre file1
y file2
, cuáles luego también volvieron a cambiar a los mismos valores (que file1
) en file3
.
Hay muchos cambios no relacionados entre file1
, file2
por lo que eso diff
por sí solo no es suficiente para determinar qué está cambiando cuando alterno este interruptor, estoy tratando de identificar los bytes únicos de entropía que cambian de file1
, 2
, 3
,...
Sé que existen herramientas como xxd
, diff
, vimdiff
, colordiff
. Simplemente no estoy seguro de cuál es la mejor manera de utilizarlos para este problema.
Respuesta1
Para conocer los bytes que cambiaron entre file1
y file2
y sus respectivos valores, utilice cmp -l
:
cmp -l file1 file2 > changes12
De manera similar para file3
y file2
. El truco está en investigar siempre en la misma dirección (aquí: apagar a encender), por eso pongo file2
al final:
cmp -l file3 file2 > changes32
Ahora puedes encontrar cambios idénticos:
comm -12 changes12 changes32
y la salida será como (ejemplo):
1629 152 112
lo que significa que el byte 1629
(decimal, la numeración comienza con 1
) cambió de 152
(octal) a 112
(octal).
Notas:
cmp -l
en mi Ubuntu "columniza" su salida. Esto significa que puede imprimir líneas con espacios iniciales; el ancho de la primera columna depende del tamaño de entrada. Supongo que es posible que algunas implementaciones no hagan esto. Hay pocas preocupaciones:- Si los archivos originales son de diferentes tamaños (probablemente no sea su caso), uno
cmp
puede generar una primera columna más ancha que la otra. En el contexto posteriorcomm
esto es inaceptable. Puede "descolumnizar" la salida canalizándola aawk '{print $1" "$2" "$3}'
. - Si el resultado no está "columnizado" (o ha sido "descolumnizado"),
comm
es posible que se queje de que los archivos no están ordenados. Necesitasort
(nosort -n
) antes de guardar enchangesAB
. Esto puede generar un orden algo inesperado (por ejemplo,23
aparecerán bytes diferentesdespuésbyte diferente100453
) que se puede solucionar canalizando la salida decomm
asort -n
.
- Si los archivos originales son de diferentes tamaños (probablemente no sea su caso), uno
changes*
Los archivos pueden ser enormes. Son intermedios y temporales, por lo que la sustitución de procesos puede ser un buen enfoque. Sin embargo, esto no es POSIX:# Korn shell syntax example comm -12 <(cmp -l file1 file2) <(cmp -l file3 file2)
La salida de
comm
se puede utilizar con otra y otra salida decmp
para filtrar mejor los cambios no relacionados:comm -12 changes12 changes32 > result1 cmp -l file4 file5 | comm -12 - result1 > result2 cmp -l file6 file5 | comm -12 - result2 > result3
Pero recuerda:
- Siempre debe hacerlo
cmp
en la misma dirección (p. ej., apagar y encender). - Cuidado con esto:Usar el mismo archivo que stdin y stdout da como resultado un archivo vacío.
… | comm -12 - result1 > result1
Está Mal.
- Siempre debe hacerlo
Documentación:
Respuesta2
Soy usuario de Windows y he usado Beyond Compare durante muchos años para comparar archivos, incluida la comparación de 3 archivos (2 a la vez) entre sí.
Parece que Beyond Compare también tiene una distribución de Linux, por lo que quizás quieras consultarla.
https://www.scootersoftware.com/download.php?zz=kb_linux_install
Sé que la versión de Windows tiene opciones para mostrar sólo las diferencias, así como muchas otras características que podrían ayudarte. No recuerdo si tienen una comparación de 3 vías o no.
No soy desarrollador ni vendedor para ellos, simplemente me gusta mucho el software.
Respuesta3
Según la respuesta de Kamil, utilicé esto para obtener lo que necesitaba:
cmp -l archivo1 archivo2 | awk '{imprimir $1" "$2" "$3}' | ordenar > cambios_12
cmp -l archivo3 archivo2 | awk '{imprimir $1" "$2" "$3}' | ordenar > cambios_32
comm -12 cambios_12 cambios_32 > cambios_comunes