cmp 是一个简单而实用的命令行工具,用于逐字节比较两个文件,并报告第一个不同之处的信息。它通常用于检查两个文件是否完全相同。


1. 命令的基本语法

cmp [选项] 文件1 文件2

2. 主要功能和输出

cmp 命令的核心功能是找出两个文件的第一个差异点。

如果两个文件完全相同cmp 不会输出任何信息,并安静地退出(退出状态码为 0)。这在脚本中非常有用,可以通过检查 $? 来判断文件是否一致。

如果两个文件不同cmp 默认会输出类似以下的信息:

文件1 文件2 不同:第 [字节序号] 行 [字节序号]
  • 字节序号:从 1 开始计数的第一个不同字节的位置。
  • 行号:这个字节所在的行号(注意,如果文件是二进制文件,这个“行”的意义不大)。

示例:
假设有两个文件 file1.txtfile2.txt,内容分别是 “hello world” 和 “hello there”。

$ cmp file1.txt file2.txt
file1.txt file2.txt differ: byte 7, line 1

这表示从第 7 个字节开始,两个文件的内容出现了差异(“world” 和 “there” 的第一个字符 ‘w’ 和 ‘t’ 不同)。


3. 常用选项

cmp 命令有一些选项可以改变其默认行为:

选项

描述

-l

详细模式。不仅报告第一个差异,还会打印出所有不同字节的序号和不同的字节值(分别以十进制显示)。

-s

静默模式。不输出任何信息,只通过退出状态码返回结果。这在脚本中特别有用。

-i SKIP

跳过两个文件开头的 SKIP 个字节再开始比较。

-i SKIP1:SKIP2

分别跳过两个文件的不同字节数。跳过 文件1SKIP1 个字节和 文件2SKIP2 个字节。

-n LIMIT

最多比较 LIMIT 个字节后就停止。


4. 退出状态码

cmp 命令的退出状态码对于脚本编程非常重要:

  • 0:文件完全相同。
  • 1:文件不同。
  • >1:发生错误(例如,文件未找到、无读取权限等)。

5. 实用示例

假设我们有三个文件:

  • a.txt: hello
  • b.txt: hello
  • c.txt: heLlo
示例 1:比较两个相同的文件
$ cmp a.txt b.txt
# 无输出,表示文件相同
$ echo $?
0
示例 2:比较两个不同的文件
$ cmp a.txt c.txt
a.txt c.txt differ: byte 3, line 1

这告诉我们,在第 3 个字节(第一个字符是字节 1,‘l’ 是字节 3)处,a.txt 是小写的 ‘l’,而 c.txt 是大写的 ‘L’。

示例 3:使用 -l 选项列出所有差异
$ cmp -l a.txt c.txt
3 154 114

输出的三列分别是:

  • 3:字节位置(序号)。
  • 154:在 文件1(a.txt)中该字节的八进制值(小写 ‘l’ 的 ASCII 码八进制是 154)。
  • 114:在 文件2(c.txt)中该字节的八进制值(大写 ‘L’ 的 ASCII 码八进制是 114)。
示例 4:在脚本中使用 -s 选项
if cmp -s file1 file2; then
    echo "文件完全相同,无需操作。"
else
    echo "文件不同,需要处理。"
fi
示例 5:跳过文件开头部分再比较

比较两个文件,但跳过 file1 的前 10 个字节和 file2 的前 20 个字节。

$ cmp -i 10:20 file1 file2

6. 与其他比较命令的区别

命令

用途

cmp

字节级比较,适用于二进制文件和文本文件。输出简洁,专注于第一个差异或所有差异的字节值。

diff

行级比较,主要用于文本文件。输出更人性化,会显示哪些行被添加、删除或修改,并可以生成补丁文件。

comm

对两个已排序的文本文件进行逐行比较,输出分为三列:只在文件1的行、只在文件2的行、两个文件共有的行。

简单总结:

  • 想知道两个文件(尤其是二进制文件)是否完全一样,用 cmp
  • 想知道两个文本文件具体有哪些不同之处,用 diff