【linux-diff】详解

Linux diff命令用于比较文件的差异。
diff以逐行的方式,比较文本文件的异同处。如果指定要比较目录,则diff会比较目录中相同文件名的文件,但不会比较其中子目录

diff [-abBcdefHilnNpPqrstTuvwy][-<行数>][-C <行数>][-D <巨集名称>]
[-I <字符或字符串>][-S <文件>][-W <宽度>][-x <文件或目录>][-X <文件>]
[--help][--left-column][--suppress-common-line][文件或目录1]
[文件或目录2]

-<行数>  指定要显示多少行的文本。此参数必须与-c或-u参数一并使用。
-a或–text  diff预设只会逐行比较文本文件。
-b或–ignore-space-change  不检查空格字符的不同。
-B或–ignore-blank-lines  不检查空白行。
-c  显示全部内文,并标出不同之处。
-C<行数>或–context<行数>  与执行"-c-<行数>"指令相同。
-d或–minimal  使用不同的演算法,以较小的单位来做比较。
-D<巨集名称>或ifdef<巨集名称>  此参数的输出格式可用于前置处理器巨集。
-e或–ed  此参数的输出格式可用于ed的script文件。
-f或-forward-ed  输出的格式类似ed的script文件,但按照原来文件的顺序来显示不同处。
-H或–speed-large-files  比较大文件时,可加快速度。
-l<字符或字符串>或–ignore-matching-lines<字符或字符串>  若两个文件在某几行有所不同,而这几行同时都包含了选项中指定的字符或字符串,则不显示这两个文件的差异。
-i或–ignore-case  不检查大小写的不同。
-l或–paginate  将结果交由pr程序来分页。
-n或–rcs  将比较结果以RCS的格式来显示。
-N或–new-file  在比较目录时,若文件A仅出现在某个目录中,预设会显示:
Only in目录:文件A若使用-N参数,则diff会将文件A与一个空白的文件比较。
-p  若比较的文件为C语言的程序码文件时,显示差异所在的函数名称。
-P或–unidirectional-new-file  与-N类似,但只有当第二个目录包含了一个第一个目录所没有的文件时,才会将这个文件与空白的文件做比较。
-q或–brief  仅显示有无差异,不显示详细的信息。
-r或–recursive  比较子目录中的文件。
-s或–report-identical-files  若没有发现任何差异,仍然显示信息。
-S<文件>或–starting-file<文件>  在比较目录时,从指定的文件开始比较。
-t或–expand-tabs  在输出时,将tab字符展开。
-T或–initial-tab  在每行前面加上tab字符以便对齐。
-u,-U<列数>或–unified=<列数>  以合并的方式来显示文件内容的不同。
-v或–version  显示版本信息。
-w或–ignore-all-space  忽略全部的空格字符。
-W<宽度>或–width<宽度>  在使用-y参数时,指定栏宽。
-x<文件名或目录>或–exclude<文件名或目录>  不比较选项中所指定的文件或目录。
-X<文件>或–exclude-from<文件>  您可以将文件或目录类型存成文本文件,然后在=<文件>中指定此文本文件。
-y或–side-by-side  以并列的方式显示文件的异同之处。
–help  显示帮助。
–left-column  在使用-y参数时,若两个文件某一行内容相同,则仅在左侧的栏位显示该行内容。
–suppress-common-lines  在使用-y参数时,仅显示不同之处。
实例1:比较两个文件

[root@localhost test3]# diff log2014.log log2013.log 
3c3   # 第一个文件的第三行通过修改变成第二个文件的第三行就能跟第二个文件一样了
< 2014-03 # <代表第一个文件的内容
--- # 两个文件的分隔符
> 2013-03 # >代表第二个文件的内容
8c8
< 2013-07
---
> 2013-08
11,12d10
< 2013-11
< 2013-12

上面的"3c3"和"8c8"表示log2014.log和log20143log文件在3行和第8行内容有所不同;"11,12d10"表示第一个文件比第二个文件多了第11和12行。
请注意,diff的结果构成,就是由若干个块组成的,下面是一个块:

3c3   # 第一个文件的第三行通过修改变成第二个文件的第三行就能跟第二个文件一样了
< 2014-03 # <代表第一个文件的内容
--- # 两个文件的分隔符
> 2013-03 # >代表第二个文件的内容

我们可以看出,一个块的构成是这样的:

1、操作   # 3c3
2、不同:
	先左文件
	后右文件

举个栗子:
我们先来看一下text1的内容:

[root@0e8b16408958 difftest]# cat text1
vth nb
bjfuvth

再来看一下text2的内容:

vth nb
bjfuvth
hh

我们来看一下diff的结果:

[root@0e8b16408958 difftest]# diff text1 text2
2a3 # 第一个文件的第二行 a代表添加,  添加一行hh才能变成文件2
> hh

我们再来看一下并排输出(常用)

[root@localhost test3]# diff log2014.log log2013.log  -y -W 50
2013-01                 2013-01
2013-02                 2013-02
2014-03               | 2013-03
2013-04                 2013-04
2013-05                 2013-05
2013-06                 2013-06
2013-07                 2013-07
2013-07               | 2013-08
2013-09                 2013-09
2013-10                 2013-10
2013-11               <
2013-12               <
[root@localhost test3]# diff log2013.log log2014.log  -y -W 50
2013-01                 2013-01
2013-02                 2013-02
2013-03               | 2014-03
2013-04                 2013-04
2013-05                 2013-05
2013-06                 2013-06
2013-07                 2013-07
2013-08               | 2013-07
2013-09                 2013-09
2013-10                 2013-10
                      > 2013-11
                      > 2013-12

说明:
"|"表示前后2个文件内容有不同
"<"表示后面文件比前面文件少了1行内容
">"表示后面文件比前面文件多了1行内容

即 < 代表了左边文件独有的内容
>代表了右边文件独有的内容
| 代表了左边和右边不同

来参考一篇大神的博客

概述:

本文将要讨论的是diff命令,diff用来比较两个文件。当然文件比较的工具很多,windows系统下面就有不错的工具可以使用,例如常用的Beyond Compare,WinMerge都是图形界面的比较工具而且使用非常方便,如果你仅仅是在windows下工作,这些GUI的比较工具绝对是首选。对于在linux环境下工作的人来说,如果每次想看两个文件的区别都要将文件下载到windows环境然后用图形工具进行比较实在是太麻烦了。那么我们必须学会使用linux环境下的比较工具diff。

扫描二维码关注公众号,回复: 6244425 查看本文章

diff如何工作,如何理解diff的执行结果

diff分析两个文件,并输出两个文件的不同的行。diff的输出结果表明需要对一个文件做怎样的操作之后才能与第二个文件相匹配【或者这么理解:与第一个文件相比,第二个文件发生了那些变化】【git diff的结果输出也是如此】。diff并不会改变文件的内容,但是diff可以输出一个ed脚本来应用这些改变。
现在让我们来看一下diff是如何工作的,假设有两个文件:

//file1.txt
I need to buy apples.
I need to run the laundry.
I need to wash the dog.
I need to get the car detailed.

//file2.txt
I need to buy apples.
I need to do the laundry.
I need to wash the car.
I need to get the dog detailed.

我们使用diff比较他们的不同:

diff file1.txt file2.txt

输出如下结果:

2,4c2,4
< I need to run the laundry.
< I need to wash the dog.
< I need to get the car detailed.
---
> I need to do the laundry.
> I need to wash the car.
> I need to get the dog detailed.

我们来说明一下该输出结果的含义,要明白diff比较结果的含义,我们必须牢记一点,diff描述两个文件不同的方式是告诉我们怎么样改变第一个文件之后与第二个文件匹配。我们看看上面的比较结果中的第一行 2,4c2,4 前面的数字2,4表示第一个文件中的行,中间有一个字母c表示需要在第一个文件上做的操作(a=add,c=change,d=delete),后面的数字2,4表示第二个文件中的行。

2,4c2,4 的含义是:第一个文件中的第[2,4]行(注意这是一个闭合区间,包括第2行和第4行)需要做出修改才能与第二个文件中的[2,4]行相匹配。
接下来的内容则告诉我们需要修改的地方,前面带 < 的部分表示左边文件的第[2,4]行的内容,而带> 的部分表示右边文件的第[2,4]行的内容,中间的 --- 则是两个文件内容的分隔符号

Normal模式

上面的部分我们说明了如何查看diff命令的结果,实际上对于上面的比较,我们使用的是diff命令的Normal模式,这也是diff命令的默认模式,也就是说diff两个文件的时候如果不加模式参数则是默认模式进行比较,其效果与(--normal)一样,我们举一些例子来说明Normal模式下的输出结果(前面已经说明了一种比较结果),为了直观查看两个文件的不同我在windows下面通过BeyondCompare工具列出两个文件的不同,而截图下面的黑色部分则是diff的比较输出截图。
第一个文件比第二个文件少了行的情况:
在这里插入图片描述
第一个文件比第二个文件多出行的情况:
在这里插入图片描述
第一个文件与第二个文件不相同的情况:
在这里插入图片描述
以上diff命令执行的时候没有指定额外的模式参数,所以其使用的是默认的Normal模式,效果与添加命令行参数--normal 是一样的。

Context模式

默认情况下的模式输出结果实际上是符合计算机的思维方式,不太直观,所以其输出结果并不能够很好的被人理解,diff命令除了默认模式之外还提供了另外两种模式,ContextUnified模式,本节我们说说如何查阅Context模式下的输出结果。diff命令应用Context模式只需要添加命令行参数 diff -c 即可,我们先看看两个案例文件:
在这里插入图片描述
接下来说明这两个文件以diff -c 方式比较的结果:
在这里插入图片描述

Unified模式

diff还有一种比较方式,也即Unified模式,使用命令行 –u 来执行该模式的比较。其比较结果与Context模式很像,但是简化了一些输出,我们看看我们的案例文件,与上面的一样:
在这里插入图片描述
使用diff –u 比较的结果:
在这里插入图片描述
可以看到其比较结果与Context模式实际上差不多,只不过将比较结果合并到一起了。

比较目录

使用diff可以比较两个目录,其比较格式是 diff directory1 directory2 查看如下目录比较结果:
在这里插入图片描述
比较两个目录的时候无非是有的文件仅仅存在于某个目录中而在另一个目录中没有,如果存在同名的文件,则比较这两个文件的不同。diff比较目录的结果我们可以结合grep命令筛选出我们想要的输出,例如仅仅输出两个目录下不同的文件而忽略掉某一个目录独有另一个目录不存在的输出记录。

一些有用的参数:

diff还提供了一些有用的参数来控制比较行为与输出结果,一些常用的参数如下:
-b --ignore-space-change 忽略空格,如果两行进行比较,多个连续的空格会被当作一个空格处理,同时会忽略掉行尾的空格差异。
-w --ignore-all-space 忽略所有空格,忽略范围比-b更大,包括很多不可见的字符都会忽略。
-B 忽略空白行。
-y 输出两列,一个文件一列,有点类似GUI的输出外观了,这种方式输出更加直观。
-W 大写W,当指定-y的时候设置列的宽度,默认是130
-x, --exclude=PAT 比较目录的时候排除指定PAT模式的文件名的比较
-i, --ignore-case 忽略两个文件中大小写的不同
-e 将比较的结果保存成一个ed脚本,之后ed程序可以执行该脚本文件,从而将file1修改成与file2的内容相同,这一般在patch的时候有用。

diff  -e  1.txt  2.txt  > script.txt

这样就是生成了一个ed可以执行的脚本文件script.txt,生成脚本文件之后我们还需要做一个操作, 在脚本文件末尾添加ed的write指令,只需要执行 echo “w” >>script.txt 将w指令附加到脚本文件的最后一行即可。
那么如何应用该脚本文件呢,可以这样使用:

ed  -  1.txt < script.txt 

注意中间的 – 符号表示从标准输入中读取,而 < script.txt 则重定向script.txt的内容到标准输入。这样执行之后1.txt的内容将与2.txt完全相同。

猜你喜欢

转载自blog.csdn.net/weixin_41687289/article/details/89671782