J'ai lu des informations sur les différences et les correctifs, mais je ne sais pas comment appliquer ce dont j'ai besoin. Je suppose que c'est assez simple, alors pour montrer mon problème, prenez ces deux fichiers:
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>
Je veux avoir une sortie, qui ressemble à ceci (l'ordre n'a pas d'importance):
<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>
La fusion doit contenir toutes les lignes selon ces règles simples:
- toute ligne qui se trouve uniquement dans l'un des fichiers
- si une ligne a la même étiquette de nom mais une valeur différente, prenez la valeur de la seconde
Je veux appliquer cette tâche dans un script bash, donc il ne doit pas nécessairement être fait avec diff et patch, si un autre programme est mieux adapté
diff
peut vous dire quelles lignes se trouvent dans un fichier mais pas dans l'autre, mais uniquement sur la granularité de lignes entières.patch
ne convient que pour apporter les mêmes modifications à un fichier similaire (peut-être une version différente du même fichier ou un fichier entièrement différent où cependant les numéros de ligne et les lignes environnantes pour chaque modification sont identiques à votre fichier d'origine). Donc non, ils ne sont pas particulièrement adaptés à cette tâche. Vous voudrez peut-être y jeter un œil,wdiff
mais la solution nécessite probablement un script personnalisé. Étant donné que vos données ressemblent à XML, vous voudrez peut-être rechercher un outil XSL.Réponses:
Vous n'en avez pas besoin
patch
; c'est pour extraire les modifications et les envoyer sans la partie inchangée du fichier.L'outil pour fusionner deux versions d'un fichier est
merge
, mais comme@vonbrand
écrit, vous avez besoin du fichier "de base" à partir duquel vos deux versions ont divergé. Pour faire une fusion sans, utilisezdiff
comme ceci:Il enfermera chaque ensemble de modifications dans les commandes de style C
#ifdef
/#ifndef
"préprocesseur", comme ceci:Si une ligne ou une région diffère entre les deux fichiers, vous obtiendrez un "conflit", qui ressemble à ceci:
Enregistrez donc la sortie dans un fichier et ouvrez-la dans un éditeur. Recherchez les endroits où
#else
apparaît et résolvez-les manuellement. Ensuite, enregistrez le fichier et exécutez-legrep -v
pour vous débarrasser des lignes restantes#if(n)def
et#endif
:À l'avenir, enregistrez la version d'origine du fichier.
merge
peut vous donner de bien meilleurs résultats à l'aide des informations supplémentaires. (Mais attention:merge
édite l'un des fichiers sur place, sauf si vous l'utilisez-p
. Lisez le manuel).la source
sed -e "s/^#else.*$/\/\/ conflict/g"
#else
lignes manuellement, dans l'éditeur pendant la résolution des conflits.merge(1)
est probablement plus proche de ce que vous voulez, mais cela nécessite un ancêtre commun à vos deux fichiers.Une façon (sale!) De le faire est:
grep(1)
pour les excluresort -u
laisse une liste triée, élimine les doublonsHumm ... quelque chose dans le sens:
echo '<resources>'; grep -v resources file1 file2 | sort -u; echo '</resources>'
pourrait faire.
la source
name
in_b_but_different_val
a une valeur de#00AABB
tri mettra cela en haut et effacera la deuxième valeur au lieu de la premièrediff3
la même manière. Exiger un fichier ancêtre commun. Pourquoi n'y a-t-il pas d'outil CLI simple qui fusionne simplement 2 fichiers ensemble en fonction de ce quidiff
s'affiche.sdiff
(1) - fusion côte à côte des différences de fichiersUtilisez l'
--output
option, cela fusionnera de manière interactive deux fichiers. Vous utilisez des commandes simples pour sélectionner une modification ou modifier une modification.Vous devez vous assurer que la
EDITOR
variable d'environnement est définie. L'éditeur par défaut pour des commandes comme "eb" est généralemented
un éditeur de ligne .la source
vim
que l' utilisation en tant que RÉDACTEUR est meilleure. Mais c'est la meilleure solution, elle vient aussi avec ladiff
commande!Voici une solution simple qui fonctionne en fusionnant jusqu'à 10 fichiers :
veuillez noter que l'argument qui vient en premier a la priorité , vous devez donc appeler:
d'obtenir des valeurs communes
b.xml
plutôt quea.xml
.script b.xml a.xml
sorties:la source
Un autre piratage horrible - pourrait être simplifié, mais: P
la source
OK, deuxième essai, maintenant en Perl ( pas de qualité de production, pas de vérification!):
la source
Un autre, en utilisant cut et grep ... (prend a.xml b.xml comme arguments)
la source
echo
est l'action par défaut, doncxargs echo
superflue. Pourquoi ne le fais-tu pas detr '\n' '|'
toute façon?