我有三个二进制文件(内存转储)。把它们称为file1
、、file2
。file3
我正在尝试调试一些软件,并且正在切换开关。
file1
= 关闭file2
= 开启file3
= 关闭
我需要知道在file1
和之间哪些字节发生了变化file2
,然后在中哪些字节也变回了相同的值(与file1
)file3
。
之间有很多不相关的变化file1
,file2
所以diff
仅凭这一点不足以让我确定当我切换此开关时发生了什么变化,我试图识别从、、、……发生变化的唯一熵file1
字节。2
3
我知道有诸如、、、之类的工具xxd
。diff
我vimdiff
只是colordiff
不确定如何最好地使用它们来解决这个问题。
答案1
要了解file1
和之间发生变化的字节file2
及其各自的值,请使用cmp -l
:
cmp -l file1 file2 > changes12
对于file3
和 也类似file2
。诀窍是始终朝同一方向调查(此处:从关闭变为打开),这就是为什么我file2
在最后加上:
cmp -l file3 file2 > changes32
现在你可以发现相同的变化:
comm -12 changes12 changes32
输出将类似于(示例):
1629 152 112
这意味着字节1629
(十进制,数字以 开头)从(八进制)1
更改为(八进制)。152
112
笔记:
cmp -l
在我的 Ubuntu 中,它的输出“分列”。这意味着它可能会打印带有前导空格的行,第一列的宽度取决于输入的大小。我猜有些实现可能不会这样做。有几个问题:- 如果原始文件大小不同(可能不是您的情况),其中一个文件
cmp
可能会生成比另一个更宽的第一列。在后面的上下文中,comm
这是不可接受的。您可以通过管道传输到 来“去列化”输出awk '{print $1" "$2" "$3}'
。 - 如果输出不是“分列的”(或已“分列”),
comm
可能会抱怨文件未排序。在保存到之前,您需要sort
(不是)。这可能会产生一些意想不到的顺序(例如,会出现不同的字节sort -n
changesAB
23
后不同的字节100453
),可以通过comm
将的输出通过管道传输到 来修复sort -n
。
- 如果原始文件大小不同(可能不是您的情况),其中一个文件
changes*
文件可能很大。它们是中间的和临时的,因此进程替换可能是一种好方法。但这是非 POSIX 的:# Korn shell syntax example comm -12 <(cmp -l file1 file2) <(cmp -l file3 file2)
的输出
comm
可以与另一个输出一起使用,以cmp
更好地过滤掉不相关的变化:comm -12 changes12 changes32 > result1 cmp -l file4 file5 | comm -12 - result1 > result2 cmp -l file6 file5 | comm -12 - result2 > result3
但要记住:
- 您始终需要
cmp
朝同一方向操作(例如,从关闭状态切换到打开状态)。 - 请注意以下几点:使用相同的文件作为 stdin 和 stdout 会导致文件为空。
… | comm -12 - result1 > result1
是错的。
- 您始终需要
文档:
答案2
我是 Windows 用户,多年来我使用 Beyond Compare 进行文件比较,包括比较 3 个文件(每次 2 个)。
Beyond Compare 似乎也有一个 Linux 发行版,所以你可能想看看。
https://www.scootersoftware.com/download.php?zz=kb_linux_install
我知道 Windows 版本有显示差异的选项,以及许多其他可能对您有帮助的功能。我不记得他们是否有三向比较。
我不是他们的开发人员或销售人员,我只是非常喜欢该软件。
答案3
根据 Kamil 的回复,我使用了这个来获得我需要的东西:
cmp -l 文件1 文件2 | awk'{打印$1" "$2" "$3}'| 排序> changes_12
cmp -l file3 file2 | awk'{打印$1““$2”“$3}'| 排序> changes_32
comm -12 changes_12 changes_32 > common_changes