Das Ergebnis von diff zwei Dateien mit getauschten Zeilen besagt, dass dieselbe Zeile zweimal fehlt

28

Ich versuche, den Befehl linux diff für zwei Dateien zu verstehen, deren Zeilen nur eine gegenseitige Permutation darstellen, aber nicht in der Lage sind, die von ihm generierte Ausgabe zu analysieren. Betrachten Sie die drei folgenden Befehle:

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

Kann mir jemand die obige kryptische Ausgabe von diff erklären.

  1. Warum werden in der Ausgabe überhaupt keine "Orangen" erwähnt?
  2. Was bedeutet 1d0und 2a2bedeuten?

Ich verstehe aus dieser Antwort, dass:

"<" bedeutet, dass die Zeile in Datei2 fehlt und ">" bedeutet, dass die Zeile in Datei1 fehlt

ABER das erklärt nicht, warum Orangen in der Ausgabe fehlen.

Aussenseiter
quelle
12
Da dies orangesder größte gemeinsame Teil der beiden Dateien ist, können Sie auf kürzeste Weise die Unterschiede zwischen den beiden Dateien ausdrücken.
Stéphane Chazelas
10
Wenn Sie eine besser lesbare Ausgabe wünschen, verwenden Sie diff -u file1 file2stattdessen einfach . Das nennt man "Unified Diff" -Format. Das ursprüngliche Diff-Format sollte sehr kompakt sein, aber einheitliche Diffs sollten viel besser lesbar sein.
Godlygeek
4
@ godlygeek oderdiff -y file1 file2
user80551

Antworten:

27

Denken Sie zum Verständnis des Berichts daran, dass dies diffeine Vorschrift ist, die beschreibt, welche Änderungen an der ersten Datei ( file1) vorgenommen werden müssen, damit sie mit der zweiten Datei ( file2) identisch ist .

Insbesondere die din- 1d0Mittel löschen und die ain- 2a2Mittel fügen hinzu .

Somit:

  • 1d0bedeutet, dass Zeile 1 in file1( apples) gelöscht werden muss . 0In der 1d0Zeile 0 steht, wo sie in der zweiten Datei ( file2) erschienen wären, wenn sie nicht gelöscht worden wären . Das bedeutet, dass beim Wechsel file2in file1(rückwärts) Zeile 1 file1nach Zeile 0 von angehängt wird file2.
  • 2a2bedeutet, die zweite Zeile ( oranges) von file2an die nun zweite Zeile von anzuhängen file1(nach dem Löschen der ersten Zeile in file1, orangesumgeschaltet auf Zeile 1)
Chaos
quelle
Was ist 0in 1d0?
Geek
@Geek siehe meine Bearbeitung
Chaos
1
@ Geek Aber sei vorsichtig, das kann Knoten im Gehirn machen =)
Chaos
das hat ja angefangen knoten zu machen :-)
Aussenseiter
13

Betrachten Sie diese Dateien:

file1:

# cat file1
apples
pears
oranges
peaches

file2:

# cat file2
oranges
apples
peaches
ananas
banana

Wie difffunktioniert es, wenn es auftragsbezogen ist?

  1. diffLiest den ersten Zeilenblock von file1und file2und versucht, gleiche Zeilen zu finden:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      -------------------------------
    ->oranges    ->oranges
      peaches      apples
                   peaches
                   ananas
                   banana
    
  2. Jetzt werden alle Zeilen übersprungen, die in beiden Dateien gleich sind. orangesDies ist nur in diesem Fall der Fall:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
      -------------------------------
    ->peaches    ->apples
                   peaches
                   ananas
                   banana
    
  3. Suchen Sie nun einen anderen Satz ähnlicher Zeilen und drucken Sie die Unterschiede aus:

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
                   apples      >apples
      -------------------------------
    ->peaches    ->peaches
                   ananas
                   banana
    
  4. Überspringen Sie die ähnlichen Zeilen

      file1        file2        differences on left (<) or right side (>)
      apples                   <apples
      pears                    <pears 
      oranges      oranges
                   apples      >apples
      peaches      peaches
      -------------------------------
    ->           ->ananas
                   banana
    
  5. Suchen Sie nach Möglichkeit identische Zeilen und drucken Sie die Unterschiede aus:

    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
             -----------------------------------------------
    

Wenn ich das tue diff file1 file2:

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

Nun ist es einfach zu erklären, was diffdie Ausgabe bedeutet:

Um file1gleich zu machen file2:

  • 1,2d0: Löschen ( d) Linien 1-2aus file1und Linie ändern 0von file2entsprechend
  • 3a2: Hänge ( a) an Zeile 3der file1Zeile 2von anfile2
  • 4a4,5: An Zeile von Zeilen von anhängen4file14-5file2

diffvergleicht file1mit file2Zeile und setzt sich Unterschiede in der temporären Speicherzeile. Nachdem file1 gleich file2 bis zum ersten Auftreten einer Linie in file1, die in tritt auch auf file2, alle Zeilen, die gleich hoch sind , bis ein Unterschied nicht erwähnt werden, oft bezeichnet als ---. In diesem Fall gibt es nur eine ähnliche Zeile, nämlich oranges. Beachten Sie, dass ich file1gleich gesagt habe file2, also file1relativ gesehen wird file2und nicht umgekehrt.

Die Ausgabe bezieht sich in diesem Fall auf die erste angegebene Datei file1.

Polym
quelle
2
Die anfängliche Erklärung gefällt mir nicht: appleskommt in beiden Dateien genauso gut vor.
ODER Mapper
1
@ORMapper Ich habe die Erklärung geändert. Klingt es jetzt klarer / besser :)?
Polym
Nicht ganz, denn jetzt hast du geschrieben "es gibt nur eine ähnliche Zeile, nämlich oranges". Falsch: Es gibt eigentlich zwei Zeilen, die nicht nur ähnlich , sondern absolut identisch sind . Einer von ihnen liest oranges, der andere liest apples. Auch Ihre Erklärung (rein auftragsbezogen) steht im Widerspruch zu Stéphanes Kommentar zur Frage (längenbezogen) - wer ist richtig?
ODER Mapper
@ORMapper Du hast "In diesem Fall" und die Zeilen davor vergessen. Ich meinte es in diesem Schritt gibt es nur eine ähnliche Zeile. Ich werde meiner Antwort nur ein Beispiel hinzufügen, damit es besser verstanden wird.
Polym
1
@ORMapper Kannst du mir auch ein Beispiel geben, das zeigt, dass die längenbasierte Antwort korrekt ist?
Polym
8

Da sind sie:

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

Das Standardausgabeformat (alt) zeigt den Unterschied zwischen den Dateien ohne umgebenden Text mit Bereichen an, in denen sich die Dateien unterscheiden.

Beispiel: 1d0 <(Löschen) bedeutet, dass die Äpfel aus der ersten Zeile von entfernt werden müssen file1, und 2a2 >(Anhängen) bedeutet, dass die Äpfel in file2der zweiten Zeile hinzugefügt werden müssen , damit beide Dateien abgeglichen werden können.

Die Dokumentation unter info differklärt es weiter:

Unterschiede ohne Kontext anzeigen

Das "normale" diffAusgabeformat zeigt jede Menge Unterschiede ohne umgebenden Kontext. Manchmal ist eine solche Ausgabe der klarste Weg, um zu sehen, wie sich die Zeilen geändert haben, ohne das Durcheinander nahezu unveränderter Zeilen (obwohl Sie mit dem Kontext oder einheitlichen Formaten ähnliche Ergebnisse erzielen können, wenn Sie 0 Kontextzeilen verwenden). Dieses Format wird jedoch nicht mehr häufig zum Versenden von Patches verwendet. Zu diesem Zweck sind das Kontextformat und das einheitliche Format überlegen. Das normale Format ist die Standardeinstellung für die Kompatibilität mit älteren Versionen diffund dem POSIX-Standard. Verwenden Sie die --normalOption, um dieses Ausgabeformat explizit auszuwählen.

Detaillierte Beschreibung des Normalformats

Das normale Ausgabeformat besteht aus einem oder mehreren Unterschieden. Jeder Block zeigt einen Bereich, in dem sich die Dateien unterscheiden. Normalformat-Hunks sehen folgendermaßen aus:

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

Es gibt drei Arten von Änderungsbefehlen. Jede Zeile besteht aus einer Zeilennummer oder einem durch Kommas getrennten Zeilenbereich in der ersten Datei, einem einzelnen Zeichen, das die Art der durchzuführenden Änderung angibt, und einer Zeilennummer oder einem durch Kommas getrennten Zeilenbereich in der zweiten Datei. Alle Zeilennummern sind die ursprünglichen Zeilennummern in jeder Datei. Die Arten von Änderungsbefehlen sind:

LaR Fügen Sie die Zeilen im Bereich R der zweiten Datei nach der Zeile L der ersten Datei hinzu. Zum Beispiel 8a12,15bedeutet, die Zeilen 12-15 von Datei 2 nach Zeile 8 von Datei 1 anzufügen; Wenn Sie Datei 2 in Datei 1 ändern, löschen Sie die Zeilen 12-15 von Datei 2.

FcT Ersetzen Sie die Zeilen in Bereich F der ersten Datei durch Zeilen in Bereich T der zweiten Datei. Dies ist wie ein kombiniertes Hinzufügen und Löschen, jedoch kompakter. Bedeutet zum Beispiel, 5,7c8,10die Zeilen 5-7 von Datei 1 so zu ändern, dass sie als Zeilen 8-10 von Datei 2 gelesen werden. oder, wenn Sie Datei 2 in Datei 1 ändern, ändern Sie die Zeilen 8-10 von Datei 2 so, dass sie als Zeilen 5-7 von Datei 1 gelesen werden.

RdL Löschen Sie die Zeilen im Bereich R aus der ersten Datei. In Zeile L wären sie in der zweiten Datei aufgetaucht, wenn sie nicht gelöscht worden wären. Zum Beispiel 5,7d3bedeutet Löschen der Zeilen 5-7 von Datei 1; oder, wenn Sie Datei 2 in Datei 1 ändern, fügen Sie die Zeilen 5-7 von Datei 1 nach Zeile 3 von Datei 2 hinzu.

Siehe auch:


Um die Orangen zu sehen, müsste man sie entweder nebeneinander oder in einem einheitlichen Kontext unterscheiden.

Zum Beispiel:

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

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