博客
关于我
Linux 下diff命令之python中difflib模块
阅读量:115 次
发布时间:2019-02-26

本文共 3770 字,大约阅读时间需要 12 分钟。

Linux中diff命令的功能为逐行比较两个文本文件,列出其不同之处。它对给出的文件进行系统的检查,并显示出两个文件中所有不同的行。

而python中difflib 模块包含用来计算字符序列间不同并进行处理的工具。它在比较文本方面十分有效,同时还包含了利用若干公共差异格式来生成报告的函数。

下面来说明,如何使用diff命令。

文本比对命令(diff)

在 Windows 下,Beyond Compare是文件比较工具。主要用途是对比两个文件夹或者文件,并将差异以颜色标示。比较范围包括目录,文档内容等。

在这里插入图片描述

在Linux中。diff命令是以逐行的方式,比较文本文件的异同处。如果该命令指定进行目录的比较,则将会比较该目录中具有相同文件名的文件,而不会对其子目录文件进行任何比较操作。

diff命令的输出格式有三种

正常格式(normal diff)

上下文格式(context diff)
合并格式(unified diff)

语法:

diff(选项)(参数)

常用选项:

-a diff预设只会逐行比较文本文件;

-b 不检查空格字符的不同;
-c:显示全部内容,并标出不同之处;
-e 此参数的输出格式可用于ed的script文件;
-u 以合并的方式来显示文件内容的不同;
-w 忽略全部的空格字符;
-y 以并列的方式显示文件的异同之处;

参数:

文件1:指定要比较的第一个文件;

文件2:指定要比较的第二个文件。

我们现在来依次讲解。

正常格式

举个例子,现在有1个文件test1.c,里面内容如下:

#include 
int main(int argc, char *argv[]){ printf("hello world!\n"); return 0;}

第二个文件:

#include 
int main(int argc, char *argv[]){ printf("hello Minger!\n"); return 0;}

正常格式下我们无需加任何选项,直接如下比对就好:

在这里插入图片描述

第一行(6c6)是一个提示,用来说明变动位置。

它分成三个部分:前面的"6",表示test1.c的第6行有变化;中间的"c"表示变动的模式是内容改变(change),其他模式还有"增加"(a,代表addition)和"删除"(d,代表deletion);后面的"6",表示变动后变成test2.c的第6行。

第二行:< printf(“hello world!\n”);

表示test1.c文件中去除第6行的内容,其中小于号表示去除。

第三行:------

表示分隔线。

第四行:> printf(“hello Minger!\n”);

表示test2.c文件中增加第2行的内容,其中大于号表示增加。

上下文格式

上面我们看到正常格式下,信息是不是很少。导致我们无法快速定位所修改的地方,经常需要打开文件才知道修改细节。所以,为了给出更多的信息,引入了上下文格式。

它的使用方法是加入c参数(代表context)。例如:

diff -c file1 file2

我们还是使用上面的文件test1.c 和 test2.c,来看看效果。

在这里插入图片描述

从上面的信息来看,第1行和第2行表示修改前及修改后的文件及更新时间。

下面的*** 3,8 ****表示test1.c文件显示的从第3行开始到第8行为止的内容。

另外,文件内容的每一行最前面,还有一个标记位。如果为空,表示该行无变化;如果是感叹号(!),表示该行有改动;如果是减号(-),表示该行被删除;如果是加号(+),表示该行为新增。

后面几行的含义类似。表示显示变动后的文件,即test2.c

合并格式

从名字上我们就可以看出,这种格式就是上面介绍那两个格式的综合版,同时这种格式也是git diff所采用的格式。

它的使用方法是加入u参数(代表unified)。

diff -u file1 file2

来看看效果:

在这里插入图片描述

从上面的输出结果信息来看:

第1行和第2行表示修改前及修改后的文件及更新时间。

第二部分,变动的位置用两个@作为起首和结束

@@ -3,6 +3,6 @@

前面的"-3,6"分成三个部分:减号表示第一个文件(即test1.c),"3"表示第3行,“6"表示连续6行。合在一起,就表示下面是第一个文件从第3行开始的连续6行。同样的,”+3,6"表示变动后,成为第二个文件从第3行开始的连续6行。

除了以上三种格式外,还有另外一直更直观的方式——并排格式。这种显示格式的命令格式如下:

在这里插入图片描述

这种格式就是以并列的格式进行显示,也很直观明了。有个“|”符号,表示这行有更改。

好了,diff命令就简单说到这里了,想要更多了解diff,可以通过man 手册查看。

使用Python标准库difflib

difflib 模块包含一些用来计算和处理序列之间差异的工具。它对于比较文本尤其有用,其中包含的函数可以使用多种常用差异格式生成报告。

两个 字符串的差异对比

本示例通过使用difflib模块实现两个字符串的差异对比,然后以版本控制风格进行输出。

下面以 difflib_data.py 模块内的测试数据:

text1 = """This module provides classes and functions for comparing sequences. It can be used for example, for comparing files, and can produce difference information in various formats,including HTML and context and unified diffs. For comparing directories and files,see also, the filecmp module."""text1_lines = text1.splitlines()text2 = """This module provides classes and functions for comparing sequences. It can be used for example, for comparing file, and can produce difference information in various format,including HTML and context and unified diff. For comparing directories and file,see also, the filecmp module."""text2_lines = text2.splitlines()

difflib_differ.py

#!/usr/local/bin/python38import difflibfrom difflib_data import *d = difflib.Differ()diff = d.compare(text1_lines, text2_lines)print('\n'.join(diff))

在将文本传递给 compare() 之前将文本分解为一系列单独的行会生成比传入大字符串更可读的输出。

在这里插入图片描述

Differ 类适用于文本行序列并产生人类可读的 增量 ,或更改指令,包括各行内的差异。Differ 生成的默认输出类似于 Unix 下的 diff 命令行工具。它包括来自两个列表的原始输入值和标记数据,以指示进行了哪些更改。

以 - 为前缀的行在第一个序列中,但不在第二个序列中。

以 + 为前缀的行在第二个序列中,但不在第一个序列中。
如果某行之间的版本之间存在增量差异,则使用前缀为 ? 的额外行来突出显示新版本中的更改。如果一条线没有改变,则在左列上打印一个额外的空白区域,使其与可能存在差异的另一个输出对齐。

其他输出格式

虽然 Differ 类展示了所有的输入行,unified diff 仅包括修改过的行和一些上下文。unified_diff() 函数产生这种输出。

#!/usr/local/bin/python38import difflibfrom difflib_data import *diff = difflib.unified_diff( text1_lines, text2_lines, lineterm='', )print('\n'.join(diff))

lineterm 参数用于告诉 unified_diff() 跳过追加新行到它返回的控制行,因为输入行不包含它们。打印时,新行将添加到所有行。对于许多流行的版本控制工具的用户来说,输出看起来应该很熟悉。

在这里插入图片描述

使用 context_diff() 产生类似的可读输出。是不是看上去跟diff命令合并格式一个格式显示。这里就不多说介绍显示信息了。

参考:https://learnku.com/docs/pymotw/difflib-character-comparison/3363

转载地址:http://zkiy.baihongyu.com/

你可能感兴趣的文章
mysql 中的all,5分钟了解MySQL5.7中union all用法的黑科技
查看>>
MySQL 中的外键检查设置:SET FOREIGN_KEY_CHECKS = 1
查看>>
Mysql 中的日期时间字符串查询
查看>>
mysql 中索引的问题
查看>>
MySQL 中锁的面试题总结
查看>>
MySQL 中随机抽样:order by rand limit 的替代方案
查看>>
MySQL 为什么需要两阶段提交?
查看>>
mysql 为某个字段的值加前缀、去掉前缀
查看>>
mysql 主从
查看>>
mysql 主从 lock_mysql 主从同步权限mysql 行锁的实现
查看>>
mysql 主从互备份_mysql互为主从实战设置详解及自动化备份(Centos7.2)
查看>>
mysql 主从关系切换
查看>>
MYSQL 主从同步文档的大坑
查看>>
mysql 主键重复则覆盖_数据库主键不能重复
查看>>
Mysql 事务知识点与优化建议
查看>>
Mysql 优化 or
查看>>
mysql 优化器 key_mysql – 选择*和查询优化器
查看>>
MySQL 优化:Explain 执行计划详解
查看>>
Mysql 会导致锁表的语法
查看>>
mysql 使用sql文件恢复数据库
查看>>