linux系统下的diff命令详解

diff分析两个文件,并输出两个文件的不同的行。diff的输出结果表明需要对一个文件做怎样的操作之后才能与第二个文件相匹配。diff并不会改变文件的内容,但是diff可以输出一个ed脚本来应用这些改变。

(1)diff命令的normal模式

假设有两个文件,test1.txt和test2.txt,内容分别如下所示:

cat test1.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.

cat test2.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 test1.txt test2.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]行的内容,中间的 --- 则是两个文件内容的分隔符号。

diff命令的normal模式,这也是diff命令的默认模式,也就是说diff两个文件的时候如果不加模式参数则是默认模式进行比较,其效果与(--normal)一样。我们举一些例子来说明Normal模式下的输出结果(前面已经说明了一种比较结果),为了直观查看两个文件的不同我在windows下面通过winmerge工具列出两个文件的不同,而截图则是diff的比较输出结果。

 由diff的比较结果可以知道第一个文件的第3行 添加内容aa之后与第二个文件的第4行一样,第一个文件的第8行添加内容77之后与第二个文件的第10行一样。

以上diff命令执行的时候没有指定额外的模式参数,所以其使用的是默认的Normal模式,效果与添加命令行参数--normal 是一样的。

(2)diff的另一种模式context模式

diff的另一种模式context模式,diff命令应用Context模式只需要添加命令行参数 diff -c  即可。还是以上述的两个文件为列,使用diff的context模式进行比较,输出结果如下:

# diff test1.txt test2.txt  -c
*** test1.txt	2020-03-10 05:16:35.448468592 +0000
--- test2.txt	2020-03-10 05:16:47.169468592 +0000
***************
*** 1,8 ****
--- 1,10 ----
  11
  22

+ aa
  33
  44

  55
  66
+ 77

前两行列出了要比较的两个文件的文件名,以及文件的修改日期和时间。文件名前面的符号是用来代表该文件的,例如***代表test1.txt,---代表test2.txt。中间的一长串**********代表分隔符。以***开头表示下面的部分为test1.txt的内容,该输出结果中没有。以---开头表示下面的内容是test2.txt的内容,前面的+号表示第一个文件需要加上该行才会与第二个文件test2.txt的内容一样。

需要注意的是这里无论+、-,这些符号显示在比较结果的哪个区域,它的含义都表示第一个文件需要做一些操作才能与第二个文件相匹配。例如+表示第一个文件需要加上这些行才与第二个文件匹配;-表示第一个文件需要删掉这些行才和第二个文件匹配;!表示第一个文件需要修改才与第二个文件匹配。

(3)diff比较目录

使用diff可以比较两个目录,其比较格式是  diff  directory1  directory2 。比较两个目录的时候无非是有的文件仅仅存在于某个目录中而在另一个目录中没有,如果存在同名的文件,则比较这两个文件的不同。比较目录的时候有两个参数很有用,-r 和 -q  ,前者表示递归比较目录中的子目录,后者表示仅仅列出两个目录中有哪些文件不同,而不去比较目录中各个文件的具体内容。

(4)常用参数

-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的时候有用。
-r 如果比较两个目录,-r参数会比较其下同名的子目录
-q 输出结果中,只指出两个文件不同,而不输出两个文件具体内容的比较,这在比较两个目录的时候很好用。我们只需要知道两个目录下那些文件做了修改,而不需要知道每个文件具体修改了那些内容。特别是当两个目录文件很多的时候。

diff  -e  test1.txt  test2.txt  > script.txt
这样就是生成了一个ed可以执行的脚本文件script.txt,生成脚本文件之后我们还需要做一个操作, 在脚本文件末尾添加ed的write指令,只需要执行 echo "w" >>script.txt 将w指令附加到脚本文件的最后一行即可。
那么如何应用该脚本文件呢,可以这样使用:
ed  -  test1.txt < script.txt 
注意中间的 – 符号表示从标准输入中读取,而 < script.txt 则重定向script.txt的内容到标准输入。这样执行之后test1.txt的内容将与test2.txt完全相同。
# cat script.txt
8a
77
.
3a
aa
.
w



# cat test1.txt
11
22

33
44

55
66
# ed  -  test1.txt < script.txt
# cat test1.txt
11
22

aa
33
44

55
66
77

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

#慧#

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值