
Eu tenho três arquivos binários (despejos de memória). Chame-os file1
, file2
, file3
. Estou tentando depurar algum software e estou alternando uma opção.
file1
= desligarfile2
= ligarfile3
= desligar
Preciso saber quais bytes foram alterados entre file1
e file2
, que também voltaram para os mesmos valores (como file1
) em file3
.
Há muitas mudanças não relacionadas entre file1
, file2
então isso diff
por si só não é suficiente para eu determinar o que está mudando quando eu alterno essa opção, estou tentando identificar os bytes únicos de entropia que mudam de file1
, 2
, 3
,…
Eu sei que existem ferramentas como xxd
, diff
, vimdiff
, colordiff
. Só não tenho certeza da melhor forma de usá-los para esse problema.
Responder1
Para saber os bytes que mudaram entre file1
e file2
e seus respectivos valores, use cmp -l
:
cmp -l file1 file2 > changes12
Da mesma forma para file3
e file2
. O truque é investigar sempre na mesma direção (aqui: desligue para ligar), por isso coloquei file2
no final:
cmp -l file3 file2 > changes32
Agora você pode encontrar alterações idênticas:
comm -12 changes12 changes32
e a saída será como (exemplo):
1629 152 112
o que significa que o byte 1629
(decimal, a numeração começa com 1
) mudou de 152
(octal) para 112
(octal).
Notas:
cmp -l
no meu Ubuntu "coluna" sua saída. Isso significa que pode imprimir linhas com espaços à esquerda, a largura da primeira coluna depende do tamanho da entrada. Acho que algumas implementações podem não fazer isso. Existem algumas preocupações:- Se os arquivos originais forem de tamanhos diferentes (provavelmente não é o seu caso), um
cmp
poderá gerar uma primeira coluna mais larga que a outra. No contexto posterior,comm
isso é inaceitável. Você pode "descolunar" a saída canalizando paraawk '{print $1" "$2" "$3}'
. - Se a saída não estiver "colunada" (ou tiver sido "descolunada"),
comm
pode reclamar que os arquivos não estão classificados. Você precisasort
(nãosort -n
) antes de salvar emchangesAB
. Isto poderá gerar uma ordem algo inesperada (por exemplo,23
aparecerão bytes diferentesdepoisbyte diferente100453
) que pode ser corrigido canalizando a saída decomm
tosort -n
.
- Se os arquivos originais forem de tamanhos diferentes (provavelmente não é o seu caso), um
changes*
os arquivos podem ser enormes. Eles são intermediários e temporários, portanto a substituição de processos pode ser uma boa abordagem. Porém, isso não é POSIX:# Korn shell syntax example comm -12 <(cmp -l file1 file2) <(cmp -l file3 file2)
A saída from
comm
pode ser usada com outra e outra saída ofcmp
para filtrar melhor as alterações não relacionadas:comm -12 changes12 changes32 > result1 cmp -l file4 file5 | comm -12 - result1 > result2 cmp -l file6 file5 | comm -12 - result2 > result3
Mas lembre-se:
- Você precisa sempre
cmp
na mesma direção (por exemplo, desligar para ligar). - Cuidado com isso:Usar o mesmo arquivo que stdin e stdout resulta em arquivo vazio.
… | comm -12 - result1 > result1
está errado.
- Você precisa sempre
Documentação:
Responder2
Sou usuário do Windows e uso o Beyond Compare há muitos anos para comparar arquivos, incluindo comparar 3 arquivos (2 de cada vez) entre si.
Parece que o Beyond Compare também tem uma distribuição Linux, então você pode querer dar uma olhada.
https://www.scootersoftware.com/download.php?zz=kb_linux_install
Eu sei que a versão para Windows tem opções para mostrar apenas diferenças, além de muitos outros recursos que podem ajudá-lo. Não me lembro se eles têm uma comparação de 3 vias ou não.
Não sou desenvolvedor nem vendedor deles, apenas gosto muito do software.
Responder3
Com base na resposta de Kamil, usei isto para conseguir o que precisava:
cmp -l arquivo1 arquivo2 | awk '{imprimir $1" "$2" "$3}' | classificar > alterações_12
cmp -l arquivo3 arquivo2 | awk '{imprimir $1" "$2" "$3}' | classificar > alterações_32
comm -12 alterações_12 alterações_32 > alterações_comuns