diff chaque ligne individuelle dans le premier fichier contre toutes les lignes dans le deuxième fichier?


2

J'ai 2 représentations TCL d'un projet qui sont générées par 2 versions différentes du même outil, appelons-les v1.tcletv2.tcl

Ces journaux sont normalement logiquement identiques à toutes fins utiles, à l'exception de l'ordre des lignes. Chaque ligne v1.tclsera trouvée quelque part exactement v2.tcllorsque les versions 1 et 2 de mon projet sont identiques.

J'aimerais pouvoir déterminer si quelqu'un a apporté une modification v2.tclqui doit être rétroportée v1.tcl(ou vice-versa) ... En d'autres termes, j'aimerais seulement voir les lignes qui ne correspondent pas. Par exemple:

  1. v1.tcl:

    foo1
    bar1
    hello1
    world1
  2. v2.tcl:

    hello1
    bar1
    foo2
    world1
    goodbye2
  3. "diff" valeur de retour:

    file1:1 foo1
    file2:3 foo2
    file2:5 goodbye2

Devrais-je juste écrire mon propre petit script? Y at-il un outil qui fait déjà cela?


@PimpJuiceIT J'en ai marre de ça, et comme c'est du code, je reçois parfois des erreurs grep: Trailing backslash. Je vérifierai les pages de manuel pour savoir si je peux les traiter comme du texte ...
IDLacrosseplayer

@PimpJuiceIT ne fait qu'exécuter des grep -vf v2.tcl v1.tclerreurs avec "barre oblique inverse", même si je le redirige quelque part comme ci-dessus.
IDLacrosseplayer

1
@PimpJuiceIT Si les fichiers d'entrée ont des lignes se terminant par des barres obliques inverses, grep génère les erreurs de fin de la barre oblique inverse. J'ai utilisé grep -Fpour les corriger et j'ai ajouté votre commentaire / réponse beaucoup plus court à la fin du mien. FYI Je n'ai pas utilisé toute la solution awk, mais j'ai ajouté bash / cut / grep pour afficher le nom du fichier et les lignes
Xen2050

@ Xen2050 Très belle solution, bonne explication sur tout ça aussi. Je n'avais aucun système Linux pour ssh afin de me tester sous Linux, donc le grep que j'ai commenté via des packages Windows GNU ou autre.
Pimp Juice IT

Réponses:


5

Si les lignes sont identiques et que vous voulez seulement savoir s'il y a des lignes supplémentaires dans un fichier ou dans un autre, vous pouvez utiliser sort & diff (et Process Substitution ici):

$ diff -B <(sort v1.tcl) <(sort v2.tcl)
2c2,3
< foo1
---
> foo2
> goodbye2

Avec diff, -Bignorer les lignes vides. Vous pouvez ensuite utiliser grep -n [pattern] filepour trouver la ligne de la tendance est à (peut - être avec un ou une combinaison de grep, cut, sed, awk), si cela importe.

Voici une réponse plus complète, indiquant le numéro de fichier et le numéro de ligne contenant les correspondances. N'utilise pas sed ou awk, seulement bash, cut, grep ... tout y est (essentiellement) dans une ligne:

diff -B <(sort v1.tcl) <(sort v2.tcl) | while read -r line; do if \
echo "$line" | grep -q "^<"; then grep -F -n -H \
"$(echo "$line"|cut -c3-)" v1.tcl ; elif echo "$line" | grep -q \
"^>"; then grep -F -n -H "$(echo "$line"|cut -c3-)" v2.tcl ; fi done

Ou divisé en plusieurs lignes:

diff -B <(sort v1.tcl) <(sort v2.tcl) | while read -r line
do
  if echo "$line" | grep -q "^<"
    then grep -F -n -H "$(echo "$line"|cut -c3-)" v1.tcl
  elif echo "$line" | grep -q "^>"
    then grep -F -n -H  "$(echo "$line"|cut -c3-)" v2.tcl
  fi
done

Et en fonction de vos fichiers d'entrée (surtout si vous avez des lignes avec des barres obliques inverses), j'utilise ces options pour read & grep:

  • read -r ne pas permettre aux barres obliques inverses d'échapper des caractères
  • grep -F Interprétez PATTERN en tant que liste de chaînes fixes (au lieu d'expressions régulières), séparées par des nouvelles lignes, dont chacune doit correspondre

De plus, en utilisant les commentaires de Pimp Juice IT , s'il y a des barres obliques inverses vers les lignes dans les fichiers en entrée, grep génère l'erreur "fichier: ligne, des barres obliques inversées". L'utilisation de l' -Foption permettant à grep de supprimer la dernière erreur de barre oblique inversée entraîne une solution beaucoup plus petite réservée à grep:

grep -FvHn -f v2.tcl v1.tcl ;grep -FvHn -f v1.tcl v2.tcl

Options de grep utilisées:

  • -f Obtenir des modèles de FILE, un par ligne.
  • -F Interprétez PATTERN en tant que liste de chaînes fixes (au lieu d'expressions régulières), séparées par des nouvelles lignes, dont chacune doit correspondre
  • -v Inverser le sens de la concordance pour sélectionner des lignes non concordantes.
  • -H Imprimer le nom du fichier pour chaque match
  • -n Préfixez chaque ligne de sortie avec le numéro de ligne basé sur 1 dans son fichier d'entrée.

Bienvenue :) Les barres obliques inverses -Ffinales posaient problème avec mon premier brouillon (non & je pense que `-r``) répondait aussi, bien que l'exemple de texte fonctionne correctement et que les lignes vierges superflues posaient également des problèmes étranges. Mais maintenant, tout semble
aller
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.