
Ich habe drei Binärdateien (Speicherauszüge). Nennen wir sie file1
, file2
, file3
. Ich versuche, eine Software zu debuggen und lege dabei einen Schalter um.
file1
= ausschaltenfile2
= einschaltenfile3
= ausschalten
Ich muss wissen, welche Bytes sich zwischen file1
und geändert haben file2
, welche sich dann auch file1
in wieder auf die gleichen Werte (wie ) geändert haben file3
.
Es gibt viele unabhängige Änderungen zwischen file1
, file2
sodass diff
mir das allein nicht ausreicht, um zu bestimmen, was sich ändert, wenn ich diesen Schalter umlege. Ich versuche, die eindeutigen Entropiebytes zu identifizieren, die sich von file1
, 2
, 3
, … ändern.
Ich weiß, dass es Tools wie xxd
, diff
, vimdiff
, gibt colordiff
. Ich bin mir nur nicht sicher, wie ich sie für dieses Problem am besten einsetzen kann.
Antwort1
file1
Um die zwischen und geänderten Bytes file2
und ihre jeweiligen Werte zu erfahren, verwenden Sie cmp -l
:
cmp -l file1 file2 > changes12
Gleiches gilt für file3
und file2
. Der Trick besteht darin, immer in die gleiche Richtung zu untersuchen (hier: von aus auf an schalten), deshalb schreibe ich file2
ans Ende:
cmp -l file3 file2 > changes32
Nun sind identische Änderungen zu finden:
comm -12 changes12 changes32
und die Ausgabe sieht wie folgt aus (Beispiel):
1629 152 112
was bedeutet, dass das Byte 1629
(Dezimal, Nummerierung beginnt mit 1
) von 152
(Oktal) in 112
(Oktal) geändert wurde.
Anmerkungen:
cmp -l
in meinem Ubuntu wird die Ausgabe in Spalten aufgeteilt. Das bedeutet, dass Zeilen mit führenden Leerzeichen gedruckt werden können. Die Breite der ersten Spalte hängt von der Eingabegröße ab. Ich vermute, dass einige Implementierungen dies nicht tun. Es gibt einige Bedenken:- Wenn die Originaldateien unterschiedliche Größen haben (was bei Ihnen wahrscheinlich nicht der Fall ist),
cmp
kann eine Datei eine breitere erste Spalte erzeugen als die andere. Im Kontext von spätercomm
ist das nicht akzeptabel. Sie können die Ausgabe „entspalten“, indem Sie sie an weiterleitenawk '{print $1" "$2" "$3}'
. - Wenn die Ausgabe nicht „spaltenweise“ ist (oder „entspaltenweise“ ist),
comm
kann es sein, dass die Dateien nicht sortiert sind. Sie müssensort
(nichtsort -n
) bevor Sie speichernchangesAB
. Dies kann zu einer etwas unerwarteten Reihenfolge führen (z. B. werden unterschiedliche Bytes23
angezeigt).nachabweichendes Byte100453
), was behoben werden kann, indem die Ausgabe voncomm
an weitergeleitet wirdsort -n
.
- Wenn die Originaldateien unterschiedliche Größen haben (was bei Ihnen wahrscheinlich nicht der Fall ist),
changes*
Dateien können riesig sein. Sie sind vorübergehend und temporär, daher kann Prozesssubstitution ein guter Ansatz sein. Dies ist jedoch nicht POSIX:# Korn shell syntax example comm -12 <(cmp -l file1 file2) <(cmp -l file3 file2)
Die Ausgabe von
comm
kann mit einer weiteren und einer weiteren Ausgabe von verwendet werden,cmp
um unabhängige Änderungen besser herauszufiltern:comm -12 changes12 changes32 > result1 cmp -l file4 file5 | comm -12 - result1 > result2 cmp -l file6 file5 | comm -12 - result2 > result3
Aber erinnere dich:
- Dabei muss immer
cmp
in die gleiche Richtung geschaltet werden (zB Ausschalten auf Einschalten). - Vorsicht vor Folgendem:Die Verwendung der gleichen Datei wie stdin und stdout führt zu einer leeren Datei.
… | comm -12 - result1 > result1
ist falsch.
- Dabei muss immer
Dokumentation:
Antwort2
Ich bin ein Windows-Benutzer und verwende Beyond Compare seit vielen Jahren zum Vergleichen von Dateien, unter anderem um drei Dateien (jeweils zwei) miteinander zu vergleichen.
Es scheint, dass Beyond Compare auch eine Linux-Distribution hat, also schauen Sie sich diese vielleicht an.
https://www.scootersoftware.com/download.php?zz=kb_linux_install
Ich weiß, dass die Windows-Version Optionen zum Anzeigen nur der Unterschiede sowie viele andere Funktionen bietet, die Ihnen möglicherweise weiterhelfen. Ich kann mich nicht erinnern, ob sie einen Drei-Wege-Vergleich haben oder nicht.
Ich bin weder in der Entwicklung noch im Vertrieb für sie tätig, mir gefällt die Software einfach sehr gut.
Antwort3
Basierend auf der Antwort von Kamil habe ich Folgendes verwendet, um das zu bekommen, was ich brauchte:
cmp -l Datei1 Datei2 | awk '{print $1" "$2" "$3}' | sort > Änderungen_12
cmp -l Datei3 Datei2 | awk '{print $1" "$2" "$3}' | sort > Änderungen_32
comm -12 Änderungen_12 Änderungen_32 > allgemeine_Änderungen