Ich habe zwei Konfigurationsdateien, das Original aus dem Paketmanager und eine von mir angepasste. Ich habe einige Kommentare hinzugefügt, um das Verhalten zu beschreiben.
Wie kann ich diff
die Konfigurationsdateien ausführen und die Kommentare überspringen? Eine kommentierte Zeile wird definiert durch:
- optionales führendes Leerzeichen (Tabulatoren und Leerzeichen)
- Hash-Zeichen (
#
) - alles andere Zeichen
Der (einfachste) reguläre Ausdruck, der die erste Anforderung überspringt, wäre #.*
. Ich habe die --ignore-matching-lines=RE
( -I RE
) -Option von GNU diff 3.0 ausprobiert , aber ich konnte sie mit dieser RE nicht zum Laufen bringen. Ich habe es auch versucht .*#.*
und .*\#.*
ohne Glück. Das buchstäbliche Setzen von line ( Port 631
) als RE
passt zu nichts und das Setzen des RE zwischen Schrägstriche hilft auch nicht.
Wie in "diff" vorgeschlagen, scheint der Geschmack von Regex zu fehlen? Ich habe versucht grep -G
:
grep -G '#.*' file
Dies scheint mit den Kommentaren übereinzustimmen, aber es funktioniert nicht für diff -I '#.*' file1 file2
.
Wie soll diese Option verwendet werden? Wie kann ich diff
bestimmte Zeilen überspringen lassen (in meinem Fall Kommentare)? Bitte schlagen grep
Sie die Datei nicht vor und vergleichen Sie die temporären Dateien nicht.
quelle
-I
Option bewirkt, dass ein Block nur dann ignoriert wird, wenn alle Zeilen mit dem regulären Ausdruck übereinstimmen. Auf diese Weise können Sie nur eine Kommentaränderung ignorieren, nicht jedoch die Kommentaränderungen, die sich in der Nähe einer Nichtkommentaränderung befinden.diff -I
sich nicht so verhält, wie ich es erwartet habe. Ich habe meine Antwort mit einem Beispiel aktualisiert, das dieses Verhalten für mich verdeutlicht.Antworten:
Laut Gilles
-I
ignoriert die Option eine Zeile nur, wenn nichts anderes in diesem Satz übereinstimmt, mit Ausnahme der Übereinstimmung von-I
. Ich habe es nicht vollständig verstanden, bis ich es getestet habe.Der Test
Drei Dateien werden in meinem Test beteiligt:
Datei
test1
:Datei
test2
:Datei
test3
:Die Befehle:
Der alternative Weg
Da es bisher keine Antwort gibt, die erklärt, wie die
-I
Option richtig verwendet wird, werde ich eine Alternative anbieten, die in Bash-Shells funktioniert:diff -u
- Unified Diff-B
- Leerzeilen ignorieren<(command)
- Eine Bash-Funktion namens Prozessersetzung, die einen Dateideskriptor für den Befehl öffnet. Dadurch ist keine temporäre Datei mehr erforderlichgrep
- Befehl zum Drucken von Zeilen (nicht) passend zu einem Muster-v
- Nicht übereinstimmende Zeilen anzeigenE
- Verwenden Sie erweiterte reguläre Ausdrücke'^\s*(#|$)'
- Ein regulärer Ausdruck, der mit Kommentaren und Leerzeilen übereinstimmt^
- Stimmt mit dem Zeilenanfang überein\s*
- Passen Sie ggf. Leerzeichen (Tabulatoren und Leerzeichen) an(#|$)
Entspricht einer Raute oder alternativ dem Ende einer Zeilequelle
Versuchen:
Bitte beachten Sie, dass der reguläre Ausdruck mit der entsprechenden Zeile in beiden Dateien übereinstimmen muss und mit jeder geänderten Zeile im Block übereinstimmt, damit er funktioniert. Andernfalls wird der Unterschied weiterhin angezeigt.
Verwenden Sie einfache Anführungszeichen, um das Muster vor dem Expandieren der Shell zu schützen und die durch Regex reservierten Zeichen (z. B. Klammern) zu umgehen.
Wir können im
diffutils
Handbuch lesen :Dieses Verhalten wird auch hier von armel gut erklärt .
Verwandte Themen: Wie kann ich ein Diff ausführen, bei dem alle Kommentare ignoriert werden?
quelle
Nach der Suche im Internet ist der alternative Weg von Lekensteyn der bessere, den ich gefunden habe.
Aber ich möchte die dif-Ausgabe als Patch verwenden ... und es gibt ein Problem, da die Zeilennummern aufgrund von "grep -v" beibehalten werden.
Also habe ich vor, diese Kommandozeile zu verbessern:
Es ist nicht perfekt, aber die Zeilennummer bleibt in der Patch-Datei erhalten.
Wenn jedoch anstelle der Kommentarzeile eine neue Zeile hinzugefügt wird, wird beim Patchen ein Hunk FAILED erzeugt, wie unten zu sehen ist.
Testen Sie jetzt unser Kommando
/ dev / fd / 62 & / dev / fd / 63 sind durch Prozessersetzung erzeugte Dateien. Die Zeile zwischen "+ Neue Zeile" und "-anderen Text" ist das Standard-Leerzeichen, das in unserem sed-Ausdruck definiert ist, um Kommentare zu ersetzen.
Und jetzt, was kommt, wenn wir diesen Patch anwenden:
Die Lösung besteht darin, das Unified Diff-Format nicht ohne -u zu verwenden
Jetzt Patch-Datei Arbeitsdatei (ohne Gewähr für Ergebnis in sehr komplexen Diff-Prozess).
quelle
diff -U0 one two
den Kontext deaktivieren. Zum Patchen gibt es eine Reihe von Tools, die möglicherweise besser geeignet sind, wie z. B. kdiff3.-U0
Option, den Kontext zu deaktivieren. Hinweis: kdiff3 ist ein grafisches Tool. Ich benötige ein automatisches Tool zum Verwalten von Git-Merge-Attributen.vimdiff
unterstützt Drei-Wege-Zusammenführungen, könnte einen Blick wert sein.Normalerweise ignoriere ich diese Unordnung entweder:
grep -v "^#" | cat -s
und Unterscheidung dieser oder ...vim -d
, um die Dateien zu betrachten. Die Syntaxhervorhebung sorgt dafür, dass Unterschiede zwischen Kommentaren und Nichtkommentaren deutlich werden. Die diff-Hervorhebung der Inline-Differenz, sodass Sie auf einen Blick sehen können, welche Werte oder Teile von Werten geändert wurden, macht dies zu meinem Favoriten.quelle
Hier ist, was ich benutze, um alle kommentierten Zeilen zu entfernen - auch die mit einem Tabulator oder Leerzeichen beginnenden - und die leeren:
oder du kannst tun
quelle