Unterschied im Leerraum zwischen zwei Dateien unter Linux

15

Ich habe zwei Dateien, die beim Vergleich mit diff anzeigen, dass sich jede Zeile geändert hat. Wenn ich sie mit diff -w(Whitespace ignorierend) vergleiche, werden die wenigen minimalen Änderungen angezeigt, die ich erwarte.

Offensichtlich gibt es einen Unterschied zwischen den Leerzeichen in jeder Datei, aber ich weiß nicht, was sie sind oder wie sie zu finden sind. Ich habe versucht, die Dateien zu bearbeiten, um sicherzustellen, dass das Leerzeichen tatsächlich Leerzeichen sind (im Gegensatz zu Tabulatoren), bin mir aber nicht sicher, was ich sonst tun soll.

Ich habe vim mit verwendet :set list on, um zu bestätigen, dass am Ende der Zeilen kein Leerzeichen steht.

Ich glaube auch, dass jede Datei Linux-Zeilenterminatoren hat, da vim die ^Mam Ende der Zeilen nicht angezeigt hat .

Romski
quelle
1
Haben Sie das Leerzeichen (am Ende einer Zeile) überprüft? Solch ein Platz wird von erkannt, diffaber viele Editoren machen diesen Platz standardmäßig nicht sichtbar.
John1024
Guter Vorschlag. Ich habe vim mit ": set list on" verwendet. Dies zeigte das "$" am Ende der Zeile und es gab kein Leerzeichen. Ich werde meine Frage aktualisieren
Romski
Wenn Sie ein vimBenutzer sind, haben Sie dann versucht, vimdiff file1 file2die Unterschiede zu ermitteln?
John1024
@ John1024 Ich wusste nichts von vimdiff, aber es sieht vielversprechend aus.
Füge
1
Vim zeigt ^ M nur an, wenn es ein Unix-Zeilenende falsch erkennt, die Datei jedoch tatsächlich ein DOS-Zeilenende hat. Normalerweise passiert dies, wenn Sie ein gemischtes Zeilenende in einer einzelnen Datei haben, z. B. wenn Sie einen Patch mit einem anderen Zeilenende als der Originaldatei anwenden. Wenn vim das korrekte Ende der DOS-Zeile erkennt, hätte es das ^ M nicht angezeigt.
Lie Ryan

Antworten:

7

Für vimBenutzer gibt es ein praktisches Hilfsprogramm, um die genauen Unterschiede zwischen Dateien anzuzeigen:

vimdiff file1 file2

Dadurch wird jede Datei in Fenstern nebeneinander und mit farblich hervorgehobenen Unterschieden abgelegt.

Einige nützliche Befehle in vimdiff

Während in vimdiff, sind einige nützliche Befehle:

  • ]c: zur nächsten Änderung springen

  • [c: zur vorherigen Änderung springen

  • ctrl-W ctrl-W: zu anderem Fenster wechseln

  • zo: offene Falten

  • zc: enge Falten

Beispiel

Hier ist ein Beispiel für vimdiffin einem xtermVergleich von zwei Versionen einer cupsKonfigurationsdatei:

Bildbeschreibung hier eingeben

Sie können sehen, dass lange Abschnitte identischer Zeilen reduziert wurden. Sie können mit wieder geöffnet werden zo.

Das Farbschema hängt von Ihren Optionseinstellungen ab. Wenn im obigen Beispiel eine Zeile in einer Datei angezeigt wird, die andere jedoch nicht, erhält diese Zeile einen dunkelblauen Hintergrund. In der anderen Datei werden die fehlenden Linien durch gestrichelte Linien angezeigt. Wenn in beiden Dateien eine Linie mit einigen Unterschieden angezeigt wird, haben die unveränderten Teile der Linien einen rosa Hintergrund und die geänderten Teile einen roten Hintergrund.

John1024
quelle
14

Auf FreeBSD- oder den meisten Linux-Systemen können Sie die Ausgabe von diff weiterleiten cat -v -e -t, um Leerraumunterschiede anzuzeigen.

diff file1 file2 | cat -vet

Tabs wird gezeigt werden , wie ^Ieine $am Ende jeder Zeile angezeigt werden , so dass Sie nachfolgende Leerzeichen sehen, und nicht druckbare Zeichen werden als angezeigt ^Xoder M-X.

Wenn Sie GNU-Coreutils haben (verfügbar auf den meisten nicht ausgelasteten Linux-Distributionen), kann dies vereinfacht werden

diff file1 file2 | cat -A

Verwenden Sie auf Busybox-Systemen catv -vet.

Mark Plotnick
quelle
2

Wurde eine der Dateien auf einem Windows-Computer bearbeitet?

Die Standard-Leitungsbeendigung unter Windows ist CRLF, unter Linux ist es einfach LF (und auf Macs war es früher CR, aber ich vermute, das hat sich seit OS X geändert).

Probieren Sie wc -ldie Dateien aus und prüfen Sie, wie viele Zeilen vorhanden sind. Prüfen Sie dann, ob der Größenunterschied mit der Anzahl der Zeilen übereinstimmt (die letzte Zeile darf nicht in einer Datei abgeschlossen sein).

Zaunpfosten
quelle
Danke für die schnelle Antwort. Eine Zeilenzählung zeigt, dass eine Datei 5 weitere Zeilen enthält (ich erwarte dies, da ich Änderungen vorgenommen habe). Ich habe eine Datei von einem Linux-Rechner bekommen und die andere wurde aus einem Code-Repository auf Linux ausgecheckt. Ich glaube, dass das Anzeigen einer Datei mit Windows-Terminatoren in vim das letzte Zeichen als ^ M anzeigt, und das ist nicht der Fall.
Romski
3
vim ist intelligent genug, um die Leitungsbeendigung automatisch zu erkennen. Weitere Informationen finden Sie unter stackoverflow.com/questions/3852868 .
Zaunpfosten
Das war mir nicht bewusst! Ich werde es noch einmal überprüfen
Romski
2

odkann helfen. Der Befehl Octal Dump kann Inhalte hexadezimal anzeigen. Auf diese Weise können Sie feststellen, welche Bytes, einschließlich Nullbytes oder unerwarteter Leerzeichen, in einer Datei enthalten sind. Mögliche häufige Ursachen sind LF gegen CRLF, Tabulatoren gegen Leerzeichen oder ASCII gegen Unicode (die häufig nur ein Null-Byte vor jedem normalerweise sichtbaren Byte haben). od -x filenamesollte eines dieser Muster offenbaren. Wenn Sie die Datei genauer betrachten möchten, ist ein "Hex-Editor" möglicherweise hilfreich. Das Schöne daran odist, dass es wie der cutBefehl in viele Unix-Systeme eingebaut ist. Daher ist häufig keine separate Installation erforderlich.

Wenn Sie Dateien benötigen, die ähnlicher sind, trkönnen Sie einige Änderungen sedvornehmen und weitere. Ich würde wahrscheinlich damit beginnen ls -lzu sehen, welche Datei größer ist, dann Bytes anzeigen, um zu sehen, was geändert werden muss, und dann eine der Dateien so ändern, dass sie ähnlicher erscheinen.

TOOGAM
quelle
1

Um herauszufinden, wo sich echte Leerzeichen und Tabulatoren befinden, können Sie diese ersetzen, indem Sie sedbeispielsweise Folgendes eingeben :

$ cat file
  line 1
  line 2
    line 6
        line 7
$ sed 's/ /-/g; s/\t/<tab>/g' file
--line-1
--line-2
<tab>line-6
<tab><tab>line-7

Und jetzt vergleichen Sie die beiden Dateien.

Chaos
quelle
Besser noch, Sie könnten diesen Filter für die Diff-Ausgabe ausführen. Oder Sie könnten den fertigen Filter in Verwendung cat, wie in superuser.com/a/913368/37154
clacke
0

Der folgende Inhalt wurde hier aus dem Abschnitt "Frage" oben kopiert, der von Romski geschrieben wurde.

Beides vimdiffund diff file1 file2 | cat -Awaren aus Sicht der Werkzeuge sehr nützlich.

Zuletzt habe ich ein weiteres Problem gefunden. Einige meiner Dateien wurden mit UTF-8 BOM codiert. Dies wurde mit hervorgehoben diff file1 file2 | cat -A. Dies zeigte sich M-oM-;M-?am Anfang der betroffenen Datei:

$ diff file1 file2 | cat -A
< package com.mycompany;$
---$
> M-oM-;M-?package com.mycompany;$

Obwohl es eine Reihe von Problemen gab, habe ich im Folgenden einige Befehle für diejenigen aufgeführt, die ihre Dateien bereinigen müssen:

# recursively remove UTF8 BOM
find . -type f -exec sed -i -e '1s/^\xEF\xBB\xBF//' {} \;

# recursively replace CRLF with LF
find . -type f -print0 | xargs -0 dos2unix
Kevin Panko
quelle