分类: LINUX
2010-03-18 00:07:01
diff(differential)
功能说明:比较文件的差异。
语 法:diff
[-abBcdefHilnNpPqrstTuvwy][-<行数>;][-C <行数>;][-D
<巨集名称>;][-I <字符或字符串>;][-S <文件>;][-W <宽度>;][-x
<文件或目录>;][-X
<文件>;][--help][--left-column][--suppress-common-line][文件或目录1][文件或目
录2]
补充说明:diff以逐行的方式,比较文本文件的异同处。所是指定要比较目录,则diff会比较目录中相同文件名的文件,但不会
比较其中子目录。
参 数:
-<行数>; 指定要显示多少行的文本。此参数必须与-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参数时,仅显示不同之处。
=========================================================================
Linux diff与patch的深入分析
http://blog.csdn.net/vrix/archive/2009/08/25/4483906.aspx
diff的输出格式分为传统格式和统一格式
1)diff的传统格式输出.
############################################
cat before.txt
输出:
This
is a line to be deleted
This is a line that will be changed
This
is a line that will be unchanged
cat after.txt
输出:
This is a line that has been changed
This
is a line that will be unchanged
This is a line that has been added
############################################
diff
before.txt after.txt
输 出:
1,2c1
< This is a line to be
deleted
< This is a line that will be changed
---
> This
is a line that has been changed
3a3
> This is a line that has
been added
############################################
注释:
传统格式的输出
1,2c1是指替换第1个文件的第1,2行到第2个文件的第2行,这里的1,2是指第1个文件的第1,2
行,c是替换的意思,最后的1是第2个文件的第1行
<号是指第1个文件更改或删除的行
---号是分割两个文件
>号是
第2个文件中增加或删除的行
3a3是指将第2个文件的第3行插入到第一个文件的第3行
也就是说第1个文件的:
< This
is a line to be deleted
< This is a line that will be changed
被
替换成第2个文件的:
> This is a line that has been changed
由于第1个文件的第3行和第
2个文件的第2行一致,所以不做修改.
由于第2个文件的第3行是第1个文件所不具有的,所以在第1个文件的最后一行增加:
>
This is a line that has been added
2)patch命令的应用
用diff的传统格式输出:
#################################
diff before.txt
after.txt >mypatch.txt
#################################
用patch修补before.txt文件,使before.txt和after.txt一致.
#################################
cat
mypatch.txt |patch before.txt
输出:
patching file before.txt
#################################
比较两个文件,现在是一致的了.
#################################
cmp
before.txt after.txt
#################################
用patch命令恢复before.txt.
#################################
patch
-R before.txt
patching file before.txt
#################################
注:-R标记告诉patch在反向上应用区别或者撤销patch.
再比较两个文件,现在不一致了.
#################################
cmp
before.txt after.txt
输出:
before.txt after.txt differ: byte 17,
line 1
#################################
3)diff的统一格式输出.
#################################
diff -u before.txt after.txt
|tee mypatch.diff
输出:
--- before.txt 2009-06-20
05:21:49.000000000 +0800
+++ after.txt 2009-06-20
04:03:16.000000000 +0800
@@ -1,3 +1,3 @@
-This is a line to be
deleted
-This is a line that will be changed
+This is a line that
has been changed
This is a line that will be unchanged
+This is a
line that has been added
#################################
注释:
diff -u选项是统一格式输出.
--- before.txt 2009-06-20
05:21:49.000000000 +0800
--- before.txt是指旧文件
+++ after.txt
2009-06-20 04:03:16.000000000 +0800
+++ after.txt是指新文件.
@@ -1,3
+1,3 @@
@@ -1,3是指第1个文件一共有3行,+1,3 @@是指第2个文件一共有3行.
-This is a line
to be deleted
-This is a line that will be changed
是被删除的行
+This
is a line that has been changed
是增加的行
This is a line that will
be unchanged
没有-号和+号是指该行不变,因为after.txt和before.txt都有这行.
+This is a
line that has been added
是增加的行
diff的统一格式比较与输出是按顺序进行的.
4)diff命令在目录中的应用.
新建old和new目录,old目录包含了初始内容,new目录包含文件的最新版本.
##########################################
mkdir
old new
echo "This is one. It's unchanged." | tee old/one new/one
echo
"This is two. It will change." > old/two
echo "This is two. It
changed.">new/two
echo "This is three. It's new" > new/three
##########################################
创建修补文件
##########################################
diff -Nur
old/ new/ >mypatch.diff
##########################################
注:-r
选项按照文件目录递归创建修补文件.
-u还是统一模式
-N是指当diff遇到一个只存在于两个树中的一个树中的文件时,默认情况下跳过文
件并且打印一个警告到stderr.
这个行为可以通过-N选项来更改,这也导致了diff认为丢失的文件实际上是存在的,但它是空的.采用这种方
式,
一个修补文件可以包括已经创建的文件.然后应用修补程序创建新的文件.
##########################################
more mypatch.diff
输
出:
diff -Nur old/three new/three
--- old/three 1970-01-01
08:00:00.000000000 +0800
+++ new/three 2009-06-20
06:55:34.000000000 +0800
@@ -0,0 +1 @@
+This is three. It's new
diff
-Nur old/two new/two
--- old/two 2009-06-20 06:55:08.000000000
+0800
+++ new/two 2009-06-20 06:55:21.000000000 +0800
@@ -1 +1
@@
-This is two. It will change.
+This is two. It changed.
##########################################
注
释:
diff -Nur old/three new/three是指下面比较old/three new/three两个文件.
因为没
有old/three文件,所以在old/three中增加+This is three. It's new
diff -Nur
old/two new/two是指下面比较old/two new/two两个文件
因为old/two与new/two的第3行不一致,所以删
除This is two. It will change.增加This is two. It changed.
打补丁到old目录,新建old/three以及更改old/two
##########################################
patch
--dir old< mypatch.diff
ls -l old/
输出:
one three
two
##########################################
恢复old目录的内容,包括删除old/three,以及恢复old/two文件
##########################################
patch
--dir old -R
ls -l old/
one two
##########################################
5)检查和合并更改
用vim突出显示单个字符的更改来表示区别.
##########################################
vim -d after.txt
before.txt
##########################################
用gui工具gvimdiff来显示两个文件.
##########################################
gvimdiff after.txt
before.txt
##########################################
新建文件orig.c
##########################################
vi orig.c
void
foo(void)
{
printf("This will be changed by me. \n");
printf("This will be unchanged,\n");
printf("This will be changed by you.\n");
}
##########################################
复制文件orig.c到me.c,更改第4行为printf("This was changed by me. \n");
##########################################
vi
me.c
void foo(void)
{
printf("This was changed by me.
\n");
printf("This will be unchanged,\n");
printf("This will be changed by you.\n");
}
##########################################
复制文件orig.c到you.c,更改第7行为printf("This was changed by you.\n");
##########################################
vi
you.c
void foo(void)
{
printf("This will be changed by
me. \n");
printf("This will be unchanged,\n");
printf("This was changed by you.\n");
}
##########################################
版本工具如cvs,subversion使用GNU合并工具称为diff3.
##########################################
diff3
me.c orig.c you.c
输出:
====1
1:3c
printf("This was
changed by me. \n");
2:3c
3:3c
printf("This will be
changed by me. \n");
====3
1:7c
2:7c
printf("This will
be changed by you.\n");
3:7c
printf("This was changed by
you.\n");
注:
在没有参数的情况下,diff3产生的输出说明了那行更改.
====1和====3指明造成同原始文件不同的是哪一个修改文
件.
编号方式基于参数序列.
也就是第1个文件和第3个文件与原文件不同.
1:3c
printf("This
was changed by me. \n");
3:3c
printf("This will be changed
by me. \n");
1:3c表示第1个文件的第3行与3:3c表示的第3个文件的第3行不同.
为什么不显示与原文件的比较呢。因为
第3个文件的第3行与源文件(第2个文件)相同.所以与哪个文件比较无所谓了.
2:7c
printf("This will be changed by you.\n");
3:7c
printf("This was changed by you.\n");
2:7c表示第2个文件的第7行与3:7c表示的第3个文件的第
7行不同.
diff3会试图为我们进行合并.合并是在源文件的基础上,依据两个新文件进行修改
源文件是第二个文件,第一个文件和第三个文件可
以互换,但他们必须有共同的祖先,就是第二个文件.
#######################################
diff3 -m me.c orig.c you.c
|cat -n
输出:
1 void foo(void)
2 {
3 printf("This was changed by me. \n");
4
5 printf("This will be unchanged,\n");
6
7 printf("This was changed by you.\n");
8 }
########################################
为了测试更复杂的环境,新建一个文件orig.c.1
内容如下:
########################################
vi
orig.c.1
void foo(void)
{
printf("This will be changed by
both of us.\n");
}
########################################
用diff3 -m再次比较输出,如下:
########################################
diff3
-m me.c orig.c.1 you.c
void foo(void)
{
<<<<<<<
me.c
printf("This was changed by me. \n");
printf("This will be unchanged,\n");
printf("This will be changed by you.\n");
||||||| orig.c.1
printf("This will be changed by both of us.\n");
=======
printf("This will be changed by me. \n");
printf("This will be unchanged,\n");
printf("This was changed by you.\n");
>>>>>>>
you.c
}
########################################
注释:以上的格式,同cvs update,需要人工合并文件的格式是一致的.
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/vrix/archive/2009/08/25/4483906.aspx