比较两个具有交换行的文件的结果表明两次丢失同一行

比较两个具有交换行的文件的结果表明两次丢失同一行

我试图理解两个文件上的 linux diff 命令,这两个文件的行只是彼此的排列,但无法理解它生成的输出。考虑以下三个命令:

[myPrompt]$ cat file1
apples
oranges
[myPrompt]$ cat file2 
oranges
apples
[myPrompt]$ diff file1 file2
1d0
< apples
2a2
> apples

有人可以解释一下 diff 的上述神秘输出吗?

  1. 为什么输出中根本没有提到“橙子”?
  2. 1d0和是什么2a2意思?

我明白从这个答案那 :

“<”表示 file2 中缺少该行,“">”表示 file1 中缺少该行

但这并不能解释为什么输出中缺少橙子。

答案1

要理解该报告,请记住这diff是说明性的,描述需要对第一个文件 ( file1) 进行哪些更改才能使其与第二个文件 ( file2) 相同。

具体来说,din1d0意味着删除ain 的2a2意思是添加

因此:

  • 1d0file1表示( )中的第1行必须删除apples0in1d0表示第 0 行是它们在第二个文件 ( ) 中出现的位置(file2如果它们没有被删除)。这意味着当更改file2为(向后)在 的第 0 行之后file1附加第 1 行时。file1file2
  • 2a2表示将第二行 ( oranges)添加file2到现在的第二行file1(删除 中的第一行后file1oranges切换到第 1 行)

答案2

考虑这些文件:

file1:

# cat file1
apples
pears
oranges
peaches

file2:

# cat file2
oranges
apples
peaches
ananas
banana

diff鉴于它是基于订单的,它是如何工作的:

  1. difffile1读取和的第一个行块file2,并尝试找到相等的行:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      -------------------------------
    ->oranges    ->oranges
      peaches      apples
                   peaches
                   ananas
                   banana
    
  2. 现在它将跳过两个文件中相同的所有行,就是oranges在这种情况下:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
      -------------------------------
    ->peaches    ->apples
                   peaches
                   ananas
                   banana
    
  3. 现在找到另一组相似的行并打印出差异:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
                   apples      >apples
      -------------------------------
    ->peaches    ->peaches
                   ananas
                   banana
    
  4. 跳过类似的行

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
                   apples      >apples
      peaches      peaches
      -------------------------------
    ->           ->ananas
                   banana
    
  5. 如果可能的话,找到相同的行,并打印差异:

    line_file1    file1    line_file2    file2        differences on left (<) or right side (>)
             1    apples                              <apples 
             2    pears                               <pears 
             3    oranges           1    oranges
                                    2    apples       >apples
             4    peaches           3    peaches
                                    4    ananas       >ananas
                                    5    banana       >banana
             -----------------------------------------------
    

现在如果我这样做diff file1 file2

# diff file1 file2
1,2d0
< apples
< pears
3a2
> apples
4a4,5
> ananas
> banana

现在很简单解释一下diff输出的含义:

使file1等于file2

  • 1,2d0:删除( d) 行1-2并相应file1修改0file2
  • 3a2:附加( a)至的3file12file2
  • 4a4,5:附加到线4file1线4-5file2

difffile1逐行比较file2并解决临时内存中的差异。制作完成后file1 等于 file2直到 中第一次出现一行file1(该行也出现在 中)之前,file2直到差异为止都相等的所有行都不会被提及,通常表示为---。在本例中,只有一条类似的行,即oranges。请注意,我说file1等于file2,所以file1是相对于file2而不是相反。

输出与给定的第一个文件相关,在本例中为file1.

答案3

他们在那里:

$ diff file1 file2
1d0
< apples
2a2
> apples
$ diff file2 file1
1d0
< oranges
2a2
> oranges

答案4

标准(旧)输出格式将显示文件之间的差异,而不会将文本与文件不同的区域包围起来。

例如:(1d0 <删除)意味着苹果需要从 的第一行删除file1,并且2a2 >(append) 表示苹果需要添加到file2第二行,这样两个文件就可以匹配。

可用的文档info diff进一步解释了这一点:

在没有上下文的情况下显示差异

“正常”diff输出格式显示了每一块差异,没有任何周围的上下文。有时,这样的输出是查看行如何变化的最清晰方法,而不会出现附近未更改的行的混乱(尽管您可以通过使用 0 行上下文来通过上下文或统一格式获得类似的结果)。然而,这种格式不再广泛用于发送补丁;为此,上下文格式和统一格式更优越。普通格式是与旧版本diff和 POSIX 标准兼容的默认格式。使用该--normal选项明确选择此输出格式。

常规格式详细说明

正常的输出格式由一组或多组差异组成;每个块都显示文件不同的一个区域。正常格式的帅哥看起来像这样:

 CHANGE-COMMAND
 < FROM-FILE-LINE
 < FROM-FILE-LINE...
 ---
 > TO-FILE-LINE
 > TO-FILE-LINE...

更改命令分为三种类型。每个文件都包含第一个文件中的行号或逗号分隔的行范围、指示要进行的更改类型的单个字符以及第二个文件中的行号或逗号分隔的行范围。所有行号都是每个文件中的原始行号。更改命令的类型有:

LaR 将第二个文件的 R 范围内的行添加到第一个文件的 L 行之后。例如,8a12,15表示将文件2的第12-15行追加到文件1的第8行之后;或者,如果将文件 2 更改为文件 1,则删除文件 2 的第 12-15 行。

FcT 将第一个文件的范围 F 中的行替换为第二个文件的范围 T 中的行。这就像组合的添加和删除,但更紧凑。例如,5,7c8,10表示将文件1的第5-7行更改为文件2的第8-10行;或者,如果将文件 2 更改为文件 1,请将文件 2 的第 8-10 行更改为文件 1 的第 5-7 行。

RdL 从第一个文件中删除R范围内的行;如果没有删除它们,L 行将出现在第二个文件中。例如,5,7d3表示删除文件1的第5-7行;或者,如果将文件 2 更改为文件 1,请将文件 1 的第 5-7 行附加到文件 2 的第 3 行之后。

也可以看看:


因此,要查看橙子,您必须并排或使用统一上下文来区分它。

在示例中:

$ diff -y file1 file2
apples                                <
oranges                             oranges
                                  > apples

$ diff -u file1 file2
@@ -1,2 +1,2 @@
-apples
 oranges
+apples

相关内容