首页>教程>Linux 命令手册> 文件内容查看与处理 >Linux diff3 命令 - 三文件比较差异与合并工具

Linux diff3 命令 - 三文件比较差异与合并工具

diff3 命令(英文全称为 difference 3)是 Linux / Unix 系统中用于逐行对比三个文件内容的命令。它可以以比较易读的形式展示差异,或生成 ed 脚本,也可以合并文件。

diff3 命令语法

使用 diff3 命令需要指定三个文件,具体的语法结构形式如下:

diff3 [OPTION]... MYFILE OLDFILE YOURFILE

语法中各部分的说明:

  • [OPTION]...: 可选的内容,用于控制输出格式、合并行为、对比方式等。
  • MYFILE:第一个文件参数。
  • OLDFILE:第二个文件参数。
  • YOURFILE:第三个文件参数。
  • 任意参数为 - 时,从标准输入读取,且只能有一个指定为 -

输出内容说明

diff3 命令根据不同的选项会输出不同的内容,如下给出不同属性形式内容的说明。

默认格式输出形式

当不使用任何选项或者使用 -T / --initial-tab选项式,默认会以差异块的形式输出内容,其具体的格式如下:

diff3_output   ::=  { hunk }
hunk           ::=  hunk_header hunk_body
hunk_header    ::=  "====" [ "1" | "" | "2" | "3" ] "\n"
hunk_body      ::=  { file_directive content_line* }   # 指令数量取决于 header
file_directive ::=  file_number ":" line_range "a" | "c" "\n"
content_line   ::=  [ SP | TAB ] text "\n"             # 默认两个空格,-T 则为一个制表符
file_number    ::=  "1" | "2" | "3"
line_range     ::=  start [ "," end ]                  # 如 "7" 或 "7,8"

解释说明:

1)hunk_header 的内容说明:

  • header==== 表示三个文件都存在不同的内容,会输出 三个文件 的指令及其内容行。
  • header====1====2====3 表示其数字对应的文件与其他两个文件的内容不同),只输出该文件的指令及其内容行,其他两个文件的内容在该块相同,不输出指令。

2)file_directive 的内容说明:

每个指定的文件会输出一行指令,其形式为 文件编号:行号范围 + ac

  • a (append):在指定行号的后面追加了内容,1:7a 表示在 MYFILE 的第 7 行后追加了内容
  • c (change):指定范围行的内容发生了改变,3:8c 表示 YOURFILE 的第 8 行的内容被修改

3)content_line 的内容说明:

  • 实际要添加或替换的文本行,以空格或者制表符开头。

ed 脚本格式输出形式

当使用 -e / -3 / -x 选项时,会输出一个可以供 ed 编辑器执行的脚本,用于将 OLDFILEYOURFILE 的差异合并到 MYFILE 中,其输出的具体格式为一系列的 ed 指令:

ed_command  ::=  range "a" "\n" text_lines "\n" "." "\n"
            |   range "c" "\n" text_lines "\n" "." "\n"
            |   range "d" "\n"
range       ::=  line | line "," line
text_lines  ::=  { text "\n" }
ed_script   ::=  { ed_command } [ "w" ] [ "q" ]

格式解释说明:

  • a:在指定行之后追加内容
  • c:修改指定行范围的内容
  • d:删除指定行范围的内容
  • 在每个插入/替换指令的后面,必须有一个单独成行的 . 表示结束。
  • 脚本通常以 w(写回文件)和 q(退出)结束,但默认的输出格式中通常不包含 wq 指令,需要用户自行添加。

合并格式输出形式

当使用 -m / --merge 选项时,输出一个合并后的文件,其中冲突部分用特殊标记标出,具体的格式为:

merged_file   ::=  { conflict_marker | common_text }
conflict_marker ::=  two_way_conflict | three_way_conflict
two_way_conflict ::=  "<<<<<<< " label_A "\n" text_A "\n" "=======" "\n" text_B "\n" ">>>>>>> " label_B "\n"
three_way_conflict ::=  "<<<<<<< " label_A "\n" text_A "\n" "||||||| " label_O "\n" text_O "\n" "=======" "\n" text_B "\n" ">>>>>>> " label_B "\n"

1)格式解释说明:

  • label_Alabel_Blabel_O:通常为 文件名--label 选项提供的名称。
  • text_A: 当前指定的文件的内容,通常是 OLDFILE
  • text_B: 当前指定的文件的内容, 通常是 YOURFILE
  • text_O: 共同祖先的文件的内容,只在三个文件都存在冲突时才出现,通常是 MYFILE

2)冲突类型说明:

  • 双文件冲突OLDFILEYOURFILE 不同,但 MYFILE 与其中之一的内容相同,会使用 <<<<<<< / ======= / >>>>>>> 来输出内容。
  • 三文件冲突:三个文件各不相同,会额外增加 ||||||| 部分显示祖先的内容。

diff3 命令示例

如下给出一些 diff3 命令的常用的使用示例,查看以下的使用示例就基本掌握 diff3 命令的使用方法。

默认对比三个文件

不使用任何的选项会,会以默认输出方式输出内容:

diff3 myfile oldfile yourfile

输出所有变化并标记冲突

使用 -A / --show-all 选项输出所有的的差异,并标记冲突:

diff3 -A myfile oldfile yourfile

生成 ed 脚本

使用 -e / --ed 选项输出 ed 编辑器可以执行的脚本:

diff3 -e myfile oldfile yourfile

为 ed 脚本追加保存退出指令

使用 -i 选项为输出的 ed 可执行的脚本的后面附加保存和退出指令:

diff3 -e -i myfile oldfile yourfile

直接输出合并后的文件

使用 -m / --merge 选项以合并形式输出内容:

diff3 -m myfile oldfile yourfile

diff3 命令选项说明

diff3 命令的选项用于控制内容的输出形式等,如下给出 diff3 命令的所有选项的详细解释说明:

选项功能说明
-A, --show-all输出所有的变更,并用括号括起冲突的部分
-e, --ed输出可以使用 ed 执行的脚本,用于将 OLDFILEYOURFILE 的变更合并到 MYFILE
-E, --show-overlap-e 选项的功能类似,但对冲突部分加括号进行标记
-3, --easy-only-e 选项的功能类似,但只合并非重叠部分的变更
-x, --overlap-only-e 选项的功能类似,但只合并重叠部分的变更
-X-x 选项的功能类似,但对冲突的部分加括号进行标记
-i向 ed 脚本的末尾追加 wq 指令
-m, --merge直接输出实际合并后的文件,无其他选项时按 -A 选项的规则输出内容
-a, --text将所有的文件当作文本文件来处理
--strip-trailing-cr去除输入中行尾的回车符
-T, --initial-tab使用前置制表符对齐内容
--diff-program PROGRAM使用指定的程序 PROGRAM 来比较文件
-L LABEL, --label LABEL使用标签 LABEL 来代替文件名,最多可重复使用 3 次来指把 3 个文件指定为标签名
--help显示帮助信息并退出
-v, --version输出版本信息并退出

结语

diff3 命令是 Linux / Unix 下用于逐行对比三个文件的工具,它支持多种输出格式:默认易读的差异形式、ed 编辑器脚本形式,以及合并结果的形式。