如何做逐行比较文件在Linux使用diff命令 - 第二部分

在这个diff命令教程系列的第一部分 ,我们讨论了命令的基础知识,包括它的工作原理,以及如何理解它的输出。 虽然这个命令行实用程序肯定有一些学习曲线,但值得一试的是,如果您的日常工作涉及在仅CLI的Linux机器上执行与文件相关的任务。

假设您已经知道diff命令的基本用法,在本教程中,我们将通过一些易于理解的示例来讨论该工具提供的各种命令行选项。

但在我们继续之前,请记住,本教程中的所有示例都已在Ubuntu 14.04中使用Bash版本4.3.11(1)和差异版本3.3进行了测试。

 

差异命令选项

1.报告文件是否相同

默认情况下,当diff命令检测到正在比较的文件是否相同时,它不会产生任何输出。

$ diff file1 file2
$

但是,存在一个命令行选项(-s),您可以使用该选项强制命令在输出中报告:

$ diff -s file1 file2
Files file1 and file2 are identical

复制上下文和统一上下文

这些基本上是diff命令可以产生其输出的两种不同格式。 使用-c命令行选项启用复制上下文,而使用-u启用统一上下文。 以下是前者的一个例子:

$ diff -c file1 file2
*** file1 2016-12-29 09:36:47.175597647 +0530
--- file2 2016-12-29 09:19:55.799558326 +0530
***************
*** 1,3 ****
Hi
! Helllo
Bye
--- 1,3 ----
Hi
! Hello
Bye

因此,在复制上下文输出格式中,不同的行由惊叹号(!)指示。

以下是统一上下文格式的示例:

$ diff -u file1 file2
--- file1 2016-12-29 09:36:47.175597647 +0530
+++ file2 2016-12-29 09:19:55.799558326 +0530
@@ -1,3 +1,3 @@
Hi
-Helllo
+Hello
Bye

在这种输出格式中行之前的 + - 符号表示不同行的版本:当 文件 2 中的行文件 从文件 2 中丢失时 ,' - ',当文件 2 中的 被添加到文件 1. 时为'+' 1.

输出'ed'脚本

diff命令还可以产生'ed'编辑器可以将原始文件(我们在本例中的file1)转换为新文件(file2)的命令。 这是你如何做到这一点:

假设file1和file2包含如下更改:

$ diff file1 file2
2c2
< Helllo
---
> Hello

现在,使用-e命令行选项来产生'ed'编辑器理解的输出,并将该输出重定向到一个文件中:

diff -e file1 file2 > out

这是在这种情况下包含的东西:

2c
Hello
.

你需要下一步是在out文件的末尾添加命令'w'。

2c
Hello
.
w

现在,运行以下命令:

ed - file1 < out

你会看到file1和file2现在是相同的。

$ diff file1 file2
$

有关此功能的更多信息,请点击此处

4.输出两列

通常,diff命令通过以下方式生成输出:

$ diff file1 file2
2c2
< Helllo
---
> Hello

但是存在一个命令行选项(-y),它指向diff以在两个单独的列中生成输出。 以下是一个例子:

$ diff -y file1 file2
Hi                               Hi
Helllo                         | Hello
Bye                              Bye

如您所见,此输出格式使用“|” 以表示不同的行。

5.隐藏公共行

如果您观察上一节(上文第4点)所示的输出,您会注意到使用-y命令行选项,输出中的diff - 也会生成公共行。 如果您需要禁止这些相同的行,您可以使用--suppress-common-lines选项。

himanshu@himanshu-desktop:~$ diff -y --suppress-common-lines file1 file2
Helllo                                   | Hello

6.显示每个变化所在的C函数

对于使用diff来比较两个C语言文件的情况,有一个命令行选项(-p)用于指导实用程序精确显示每个更改所处的C函数。例如,假设这两个C文件是:

file1.c:

#include<stdio.h>

void compare(float x, float y)
{
if(x == y) // incorrect way
{
printf("\n EQUAL \n");
}
}


int main(void)
{
compare(1.234, 1.56789);

return 0;
}

file2.c:

#include<stdio.h>

void compare(float x, float y)
{
if(x == y)
{
printf("\n EQUAL \n");
}
}


int main(void)
{
compare(1.234, 1.56789);

return 0;
}

以下是两个文件正常比较时的输出:

$ diff file1.c file2.c 
5c5
< if(x == y) // incorrect way
---
> if(x == y)

这是输出,当使用-p选项比较文件时:

$ diff -p file1.c file2.c 
*** file1.c 2016-12-29 11:45:36.587010816 +0530
--- file2.c 2016-12-29 11:46:39.823013274 +0530
***************
*** 2,8 ****

void compare(float x, float y)
{
! if(x == y) // incorrect way
{
printf("\n EQUAL \n");
}
--- 2,8 ----

void compare(float x, float y)
{
! if(x == y)
{
printf("\n EQUAL \n");
}

所以,您可以看到,使用-p ,diff可以更详细地查看更改位置,指示使用感叹号(!)的不同行。

递归比较子目录

diff命令还允许您递归地比较子目录,但这不是其默认行为。 我想说的是,如果你采取以下情况:

$ diff diff-files/ second-diff-files/
diff diff-files/file1 second-diff-files/file1
1c1
< Hi
---
> i
diff diff-files/file2 second-diff-files/file2
2c2
< Hello
---
> ello

diff命令仅比较顶级目录中的文件,但是如果使用命令行选项-r(用于递归差异),则会看到甚至比较子目录中存在的文件:

$ diff -r diff-files/ second-diff-files/
diff -r diff-files/file1 second-diff-files/file1
1c1
< Hi
---
> i
diff -r diff-files/file2 second-diff-files/file2
2c2
< Hello
---
> ello
diff -r diff-files/more-diff-files/file1 second-diff-files/more-diff-files/file1
1c1
< Hi
---
> i
diff -r diff-files/more-diff-files/file2 second-diff-files/more-diff-files/file2
2c2
< Hello
---
> ello

8.将不存在的文件视为空

diff命令还提供了一个选项,您可以使用该选项指导该工具将不存在的文件视为空。 例如,如果将file1与file3(不存在)进行比较,则diff的默认行为是产生错误:

$ diff file1 file3
diff: file3: No such file or directory

这本身并不错; 其实这是完美的。 但是可能有些情况下,您不希望diff命令在这种情况下抛出错误(作为bash脚本的一部分可能是?),那么对于这些​​情况,您可以使用-N命令行选项强制命令将不存在的文件视为空,并继续比较。

$ diff -N file1 file3
1,5d0
< Hi
<
< Helllo
<
< Bye

结论

如果您正确地浏览了本教程系列的两个部分,并且练习了文章所包含的所有示例,那么就不会说这个工具有一个很好的命令。 当然,我们不能在本系列中讨论与diff有关的一切,但请放心,许多重要的功能/功能已被涵盖。

对于那些想要了解更多实用程序的手册页面总是在那里。 而且不用说你应该经常使用不同的文件集,以便模拟不同的用例。

赞(52) 打赏
未经允许不得转载:优客志 » 系统运维
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏