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 的内容说明:
每个指定的文件会输出一行指令,其形式为 文件编号:行号范围 + a 或 c:
a(append):在指定行号的后面追加了内容,1:7a表示在MYFILE的第 7 行后追加了内容c(change):指定范围行的内容发生了改变,3:8c表示YOURFILE的第 8 行的内容被修改
3)content_line 的内容说明:
- 实际要添加或替换的文本行,以空格或者制表符开头。
ed 脚本格式输出形式
当使用 -e / -3 / -x 选项时,会输出一个可以供 ed 编辑器执行的脚本,用于将 OLDFILE 和 YOURFILE 的差异合并到 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(退出)结束,但默认的输出格式中通常不包含w和q指令,需要用户自行添加。
合并格式输出形式
当使用 -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_A、label_B、label_O:通常为文件名或--label选项提供的名称。text_A: 当前指定的文件的内容,通常是OLDFILEtext_B: 当前指定的文件的内容, 通常是YOURFILEtext_O: 共同祖先的文件的内容,只在三个文件都存在冲突时才出现,通常是MYFILE。
2)冲突类型说明:
双文件冲突:OLDFILE和YOURFILE不同,但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 执行的脚本,用于将 OLDFILE 到 YOURFILE 的变更合并到 MYFILE |
-E, --show-overlap | 与 -e 选项的功能类似,但对冲突部分加括号进行标记 |
-3, --easy-only | 与 -e 选项的功能类似,但只合并非重叠部分的变更 |
-x, --overlap-only | 与 -e 选项的功能类似,但只合并重叠部分的变更 |
-X | 与 -x 选项的功能类似,但对冲突的部分加括号进行标记 |
-i | 向 ed 脚本的末尾追加 w 和 q 指令 |
-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 编辑器脚本形式,以及合并结果的形式。