理解 diff 命令
posted on 28 Sep 2015 under category translation
原文在 2009/04/17 发表于 http://unix.worldiswelcome.com/understanding-the-diff-command-in-unix
Unix 系统管理员来经常需要去知道两个文件之间有什么差异. diff
命令就是干这个的. 我现在就准备讲讲 diff
. 它是一个经常被用到却不是很被了解的命令. 我希望 Unix 使 用者在读完这篇文章之后能够正确了解这个命令的用途并从中获益.
另外一个有用的命令是:
comm
命令.
我们用到示例文件分别是 first 文件和 second 文件. 如下:
wiw_labs:$ nl first
1 computer
2 modem
3 monitor
4 phone
5 switch
wiw_labs:$ nl second
1 cable
2 mobile
3 screen
4 modem
5 phone
6 server
diff
命令可以用来比较这两个文件之间的差异.
diff
通常这样使用:
diff first_file second_file
这条命令意即: first_file 和 second_file 有什么不同
diff
命令的运作原理就是, 想法设法的让 first 文件和 second 文件一样. 它通过 更改(c), 删除(d) first 文件中的行以使其和 second 文件一模一样. 如果需要, 它 还会把 second 文件中的行附加到 first 文件中. 示例中的 diff
就是通过下面的 这些步骤来生成这两个文件的差异报告的:
它从 first 文件和 second 文件的第 1 行开始. 如果它们不一样, diff
便顺着 first 文件往下找, 直到找到和 second 文件中相似的条目.
如果在 first 文件中没有找到和 second 文件第 1 行相同的行, 它就再从 second 文件的第 2 行开始. 它会在 first 文件中开始找. 然后提议做什么(附加, 更改或删除)
理论讲得够多了. 我们来点实际例子好解释的更通透一点. 我把这两个文件并排来放, 好理 解起来更容易一些. 另外行号也一并显示了出来.
$ paste first second|nl
1 computer cable
2 modem mobile
3 monitor screen
4 phone modem
5 switch phone
6 server
$ diff first second
1c1,3
< computer
—
> cable
> mobile
> screen
3d4
< monitor
5c6
< switch
—
> server
现在, 看一下上面 paste
命令带行号的输出. 注意下面几点:
first 文件的第 2 行(modem) 和 second 文件的第 4 行(modem) 一致. 所以, 如果 我们把 first 文件中的第 1 行换成 second 文件中的 1 到 3 行, 这两个文件的第 一部分便都一样了. 输出看起来就会是这样的:
$ paste first second|nl
1 cable cable
2 mobile mobile
3 screen screen
4 modem modem
5 monitor phone
6 phone server
7 switch
first 文件的第 4 行(phone) 和 second 文件的第 5 行一致. 这意味着如果我们删 除 first 文件中的第 3 行(也就是目前的第 4 行), 这两个文件的第二部分便都一样 了.
$ paste first second|nl
1 cable cable
2 mobile mobile
3 screen screen
4 modem modem
5 phone phone
6 switch server
first 文件的第 5 行(switch)可用 second 文件的第 6 行(server)替换. 至此, 这 两个文件完全一样了.
$ paste first second|nl
1 cable cable
2 mobile mobile
3 screen screen
4 modem modem
5 phone phone
6 server server
现在, diff
命令的输出更容易理解了:
1c1,3: 更改 first 文件的第一行为 second 文件的 1 到 3 行
3d4: 从 first 文件中删除第 3 行(modem).
5c6: 更改 first 文件中的第 5 行(switch) 为 second 文件中的第 6 行 (server)
反过来再看一下:
$ paste second first | nl
1 cable computer
2 mobile modem
3 screen monitor
4 modem phone
5 phone switch
6 server
$ diff second first
1,3c1
< cable
< mobile
< screen
—
> computer
4a3
> monitor
6c5
< server
—
> switch
我们看到 first 文件的第 4 行(modem) 和 second 文件的第 2 行一致. 所以如果 我们把 first 文件的 1 到 3 行替换为 second 文件的第 1 行, 我们得到如下输出:
$ paste second first | nl
1 computer computer
2 modem modem
3 phone monitor
4 server phone
5 switch
现在, second 文件的第 3 行(monitor) 在 first 文件中并不存在. 所以, 把它附 加到 first 文件的第 4 行(modem)后面. 要记住 diff
命令的输出中的行号永远指 的是原始的行号. 现在, 输出看起来是这样的:
$ paste second first | nl
1 computer computer
2 modem modem
3 monitor monitor
4 phone phone
5 server switch
first 文件的第 6 行(server)需要改成 second 文件的第 5 行(switch). 更改之后, 两个文件便都一样了:
1 computer computer
2 modem modem
3 monitor monitor
4 phone phone
5 switch switch
所以 diff
命令的输出意即:
1,3c1: 把 first 文件的第 1 到 3 行改为 second 文件的第 1 行.
4a3: 在 first 文件的第 4 行(modem)后面附加上 second 文件的第 3 行 (monitor).
6c5: 把 first 文件的第 6 行(server)改为 second 文件的第 5 行(switch).