Ich habe über Diff und Patch gelesen, kann aber nicht herausfinden, wie ich das, was ich brauche, anwenden soll. Ich denke, es ist ziemlich einfach, also nimm diese zwei Dateien, um mein Problem zu zeigen:
a.xml
<resources>
<color name="same_in_b">#AAABBB</color>
<color name="not_in_b">#AAAAAA</color>
<color name="in_b_but_different_val">#AAAAAA</color>
<color name="not_in_b_too">#AAAAAA</color>
</resources>
b.xml
<resources>
<color name="same_in_b">#AAABBB</color>
<color name="in_b_but_different_val">#BBBBBB</color>
<color name="not_in_a">#AAAAAA</color>
</resources>
Ich möchte eine Ausgabe haben, die so aussieht (Reihenfolge spielt keine Rolle):
<resources>
<color name="same_in_b">#AAABBB</color>
<color name="not_in_b">#AAAAAA</color>
<color name="in_b_but_different_val">#BBBBBB</color>
<color name="not_in_b_too">#AAAAAA</color>
<color name="not_in_a">#AAAAAA</color>
</resources>
Die Zusammenführung sollte alle Zeilen nach diesen einfachen Regeln enthalten:
- Jede Zeile, die sich nur in einer der Dateien befindet
- Wenn eine Zeile den gleichen Namen, aber einen anderen Wert hat, wird der Wert aus der zweiten übernommen
Ich möchte diese Aufgabe in einem Bash-Skript anwenden, damit es nicht unbedingt mit diff und patch fertig werden muss, wenn ein anderes Programm besser passt
diff
kann Ihnen sagen, welche Zeilen sich in einer Datei befinden, aber nicht in der anderen, sondern nur in der Granularität ganzer Zeilen.patch
eignet sich nur, um dieselben Änderungen an einer ähnlichen Datei vorzunehmen (möglicherweise eine andere Version derselben Datei oder eine völlig andere Datei, bei der jedoch die Zeilennummern und die umgebenden Zeilen für jede Änderung mit Ihrer Originaldatei identisch sind). Nein, sie sind für diese Aufgabe nicht besonders geeignet. Vielleicht möchten Sie einen Blick darauf werfen,wdiff
aber für die Lösung ist wahrscheinlich ein benutzerdefiniertes Skript erforderlich. Da Ihre Daten wie XML aussehen, sollten Sie nach einem XSL-Tool suchen.Antworten:
Das brauchst du nicht
patch
; Es dient zum Extrahieren und Weiterleiten von Änderungen ohne den unveränderten Teil der Datei.Das Tool zum Zusammenführen von zwei Versionen einer Datei ist
merge
, aber wie@vonbrand
geschrieben, benötigen Sie die "Basis" -Datei, von der Ihre beiden Versionen abweichen. Um eine Zusammenführung ohne sie durchzuführen, verwenden Siediff
Folgendes:Es wird jede Reihe von Änderungen in C-Stil
#ifdef
/#ifndef
"Präprozessor" -Befehlen enthalten, wie folgt :Wenn sich eine Linie oder ein Bereich zwischen den beiden Dateien unterscheidet, tritt ein "Konflikt" auf, der folgendermaßen aussieht:
Speichern Sie die Ausgabe in einer Datei und öffnen Sie sie in einem Editor. Suchen Sie nach Orten, an denen sie
#else
auftauchen, und beheben Sie sie manuell. Speichern Sie dann die Datei und führen Sie sie ausgrep -v
, um die verbleibenden#if(n)def
und#endif
Zeilen zu entfernen:Speichern Sie in Zukunft die ursprüngliche Version der Datei.
merge
Mit Hilfe der zusätzlichen Informationen können Sie viel bessere Ergebnisse erzielen. (Aber seien Sie vorsichtig:merge
Bearbeiten Sie eine der Dateien an Ort und Stelle, es sei denn, Sie verwenden sie-p
. Lesen Sie das Handbuch.)quelle
sed -e "s/^#else.*$/\/\/ conflict/g"
#else
Zeilen während der Konfliktlösung im Editor manuell entfernen .merge(1)
ist wahrscheinlich näher an dem, was Sie wollen, aber das erfordert einen gemeinsamen Vorfahren für Ihre beiden Dateien.Eine (schmutzige!) Art, es zu tun, ist:
grep(1)
schließe sie mit aussort -u
hinterlässt eine sortierte Liste, entfernt DuplikateHumm ... etwas in der Art:
echo '<resources>'; grep -v resources file1 file2 | sort -u; echo '</resources>'
könnte tun.
quelle
name
in_b_but_different_val
Wert#00AABB
sort lautet, wird der Wert darüber gesetzt und der zweite Wert anstelle des ersten gelöschtdiff3
funktioniert das genauso. Gemeinsame Vorfahrendatei erforderlich. Warum gibt es kein einfaches CLI - Tool , das nur verschmilzt 2 Dateien zusammen auf , wasdiff
zeigt.sdiff
(1) - Nebeneinander Zusammenführen von DateidifferenzenVerwenden Sie die
--output
Option, um zwei beliebige Dateien interaktiv zusammenzuführen. Sie verwenden einfache Befehle , um eine Änderung auszuwählen oder zu bearbeiten.Sie sollten sicherstellen, dass die
EDITOR
Umgebungsvariable festgelegt ist. Der Standardeditor für Befehle wie "eb" ist normalerweiseed
ein Zeileneditor .quelle
vim
als EDITOR besser zu gebrauchen. Dies ist jedoch die beste Lösung, die auch mit demdiff
Befehl geliefert wird!Hier eine einfache Lösung, die das Zusammenführen von bis zu 10 Dateien ermöglicht :
Bitte beachten Sie, dass das zuerst kommende Argument Vorrang hat. Sie müssen also Folgendes anrufen:
um gemeinsame Werte zu vermeiden,
b.xml
anstatta.xml
.script b.xml a.xml
outs:quelle
Ein weiterer schrecklicher Hack - könnte vereinfacht werden, aber: P
quelle
OK, zweiter Versuch, jetzt in Perl ( keine Produktionsqualität, keine Prüfung!):
quelle
Ein anderes, mit cut und grep ... (nimmt a.xml b.xml als Argumente)
quelle
echo
ist die Standardaktion,xargs echo
ist also überflüssig. Warum gehst du nicht einfachtr '\n' '|'
sowieso?