IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Scripts/Batch Discussion :

Deux boucles FOR pour comparer deux fichiers ligne par ligne et une condition IF [Batch]


Sujet :

Scripts/Batch

  1. #1
    Membre à l'essai
    Homme Profil pro
    bidouilleur
    Inscrit en
    Novembre 2012
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 44
    Points : 24
    Points
    24
    Par défaut Deux boucles FOR pour comparer deux fichiers ligne par ligne et une condition IF
    Bonsoir, Je reviens vers vous car j'ai un problème pour comparer deux fichiers ligne par ligne et récupérer le résultat dans deux fichiers de sortie différents en fonction de si la ligne du fichier1 testée existe dans le fichier2 ou non.

    La ligne de fichier1.txt existe dans fichier2.txt --> je recopie la ligne dans sortie1.txt
    La ligne de fichier1.txt n'existe pas dans fichier2.txt --> je recopie la ligne dans sortie2.txt

    Pour faire ça j'imbrique deux boucles for et je test avec un if LigneFichier1==LigneFichier2.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for /f "delims=" %%d in ('type !fichier1!') do for /f "delims=" %%e in ('type !fichier2!') do if "%%d" EQU "%%e" (
    	echo [la ligne %%d existe]>>sortie1.txt
    ) else (
    	echo [la ligne %%d n'existe pas]>>sortie2.txt
    )
    Jusque la pas de soucis, le problème c'est que je me retrouve avec dans les fichiers de sortie X fois la même ligne, ou X représente le nombre de lignes total de fichier2.txt.

    Je me retrouve donc dans sortie2.txt (par exemple) ce genre de ligne répétées autant de fois que le nombre de ligne total dans fichier2.txt :

    [la ligne Ma.ligne.en.question n'existe pas]
    [la ligne Ma.ligne.en.question n'existe pas]
    [la ligne Ma.ligne.en.question n'existe pas]
    [la ligne Ma.ligne.en.question n'existe pas]
    [la ligne Ma.ligne.en.question n'existe pas]
    [la ligne Ma.ligne.en.question n'existe pas]

    et dans sortie1.txt :

    [la ligne ma.première.ligne existe]
    [la ligne ma.deuxième.ligne existe]
    [la ligne ma.troisième.ligne existe]
    [la ligne ma.première.ligne existe]
    [la ligne ma.deuxième.ligne existe]
    [la ligne ma.troisième.ligne existe]
    [la ligne ma.première.ligne existe]
    [la ligne ma.deuxième.ligne existe]
    [la ligne ma.troisième.ligne existe]
    [la ligne ma.première.ligne existe]
    [la ligne ma.deuxième.ligne existe]
    [la ligne ma.troisième.ligne existe]

    Etc...

    Alors que je souhaite obtenir dans sortie2.txt:

    [la ligne Ma.ligne.en.question n'existe pas]
    [la ligne une.autre.ligne.encore n'existe pas]

    Etc...
    et dans sortie1.txt:

    [la ligne ma.première.ligne existe]
    [la ligne ma.deuxième.ligne existe]
    [la ligne ma.troisième.ligne existe]

    Donc la question, est il possible de faire deux commande type sur deux fichiers différents depuis une même boucle FOR. Mais je me doute bien que non, mais sait-on jamais...

    Ou bien lorsque une ligne est trouvé dans les deux fichiers, terminer (ou sortir de) la boucle du deuxième FOR tout en continuant la boucle du premier FOR.
    Je ne sais pas si je suis clair la ou tout autre astuces palliative me conviendra du moment que j'obtient le résultat escompté.

    Merci par avance de votre aide.

  2. #2
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    Avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Vivre
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2006
    Messages : 2 895
    Points : 4 325
    Points
    4 325
    Par défaut
    Salut Christophe.G,

    Si tu veux faire avec deux boucles FOR il ne faut pas enregistrer de sortie dans la deuxième boucle mais à la fin de celui ci.
    Pour cela il faudrait ajouter une variable qui stipulerait si la ligne a été trouvé dans la deuxième boucle, puis traiter la sortie en fonction de cette variable.

    Sinon une solution serait d'utiliser la fonction FIND, (exploiter: FIND /C) (éventuellement FINDSTR) pour déterminer si la ligne est présente dans le fichier et traiter la sortie en fonction de ce résultat.

  3. #3
    Membre expert
    Avatar de sachadee
    Homme Profil pro
    AMI DU BAT
    Inscrit en
    Janvier 2013
    Messages
    1 478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Brésil

    Informations professionnelles :
    Activité : AMI DU BAT
    Secteur : Distribution

    Informations forums :
    Inscription : Janvier 2013
    Messages : 1 478
    Points : 3 768
    Points
    3 768
    Par défaut
    Pour que ça soit un peu plus clair :

    Comme l'a justement dit Vodiem traite le résultat dans la première boucle en mettant un switch par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    setlocal enabledelayedexpansion
    
    for /f "delims=" %%d in ('type !fichier1!') do (
      set $sw=0
      for /f "delims=" %%e in ('type !fichier2!') do if "%%d" EQU "%%e" set "$sw=1"
      if !$sw!=1 (echo [la ligne %%d existe]>>sortie1.txt
       ) else (
      echo [la ligne %%d n'existe pas]>>sortie2.txt
      )
    )
    Avec un Find le traitement serait effectivement beaucoup plus rapide.
    ________________________________
    Un p'tit coup de pouce ça fait toujours plaisir, pensez-y !
    ________________________________

  4. #4
    Membre à l'essai
    Homme Profil pro
    bidouilleur
    Inscrit en
    Novembre 2012
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 44
    Points : 24
    Points
    24
    Par défaut
    Tout d'abord merci de votre attention. Alors j'avais justement essayé avec un switch comme ça, mais ça ne fonctionnait pas, certainement un problème de syntaxe.
    La maintenant ça fonctionne bien (avec if !$sw!==1 au lieu de if !$sw!=1) mais seulement pour sortie2.txt.
    En ce qui concerne sortie1.txt j'ai toujours:

    [la ligne ma.première.ligne existe]
    [la ligne ma.deuxième.ligne existe]
    [la ligne ma.troisième.ligne existe]
    [la ligne ma.première.ligne existe]
    [la ligne ma.deuxième.ligne existe]
    [la ligne ma.troisième.ligne existe]
    [la ligne ma.première.ligne existe]
    [la ligne ma.deuxième.ligne existe]
    [la ligne ma.troisième.ligne existe]
    [la ligne ma.première.ligne existe]
    [la ligne ma.deuxième.ligne existe]
    [la ligne ma.troisième.ligne existe]

    au lieu de:

    [la ligne ma.première.ligne existe]
    [la ligne ma.deuxième.ligne existe]
    [la ligne ma.troisième.ligne existe]

    sauf pour une des ligne qui elle ne s'affiche qu'une seule fois (la deuxième du fichier sortie1.txt la, j'ai du mal à comprendre) sinon les autres lignes sont répétées une fois de moins que le nombre total de lignes présentes dans !fichier2!.
    Sinon en ce qui concerne FIND /C, c'est certainement plus rapide, ceci dit les fichiers ne sont pas très long, le traitement ce fait en moins d'une seconde (après c'est vrai que mis bout à bout à force chaques seconde compte d'autant qu'un des deux fichiers est lui susceptible de s'allonger). Je regarderai certainement du coté la, mais en tout cas ça ne résoudra pas mon problème d'avoir deux fichiers en sortie.
    J'espère qu'une solution existe et ne pas être obligé de supprimer les doublons par la suite, ce serait crado. Donc si vous avez une idée pour mon sortie1.txt ce serait super.

  5. #5
    Membre à l'essai
    Homme Profil pro
    bidouilleur
    Inscrit en
    Novembre 2012
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 44
    Points : 24
    Points
    24
    Par défaut
    Bon j'ai résolu (du moins contourné) le problème. Je traite en deux fois, mes deux boucle -> sortie1, de nouveau mes deux boucles -> sortie2.
    De toute façon j'étais obligé de procéder de cette manière pour une autre raison donc... je manque réflexion.
    En tout cas si c'était faisable en même temps je veux bien connaitre la solution quand même.

  6. #6
    Membre expert
    Avatar de sachadee
    Homme Profil pro
    AMI DU BAT
    Inscrit en
    Janvier 2013
    Messages
    1 478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Brésil

    Informations professionnelles :
    Activité : AMI DU BAT
    Secteur : Distribution

    Informations forums :
    Inscription : Janvier 2013
    Messages : 1 478
    Points : 3 768
    Points
    3 768
    Par défaut
    En utilisant findstr :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    @echo off
    for /f "delims=" %%d in ('type !fichier1!') do Findstr "%%d" fichier2.txt >nul && echo [la ligne %%d existe]>>sortie1.txt || echo [la ligne %%d n'existe pas]>>sortie2.txt
    ________________________________
    Un p'tit coup de pouce ça fait toujours plaisir, pensez-y !
    ________________________________

  7. #7
    Membre à l'essai
    Homme Profil pro
    bidouilleur
    Inscrit en
    Novembre 2012
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 44
    Points : 24
    Points
    24
    Par défaut
    Ca à effectivement l'air de marcher impeccable, du coup je suis intéressé à procéder de cette manière.
    Le seul soucis, c'est que ça plante car en début du fichier1 il y a quelques lignes commentées qui contiennent donc des caractères spéciaux qui ne passent pas avec findstr. Le / et * qui donne un commentaire comme ceci:

    /* Ici une ligne
    *
    * encore une ligne
    * Fin du commentaire
    */

    Il y a-t'il moyen d'échapper ces caractères ?

    A un autre endroit de mon script j'avais ce genre de problèmes pour rechercher/manipuler une chaîne avec des caractères spéciaux, j'ai contourné le problème de manière vraiment pas propre, en récupérant chaque lignes dans une variable, et en manipulant la variable pour remplacer mes caractères spéciaux par une chaîne de caractère (genre \\ changé en xxxy) puis traitement avec sed et de nouveau manipulation de variables (xxxy changé en \\) pour remettre les caractères spéciaux.
    C'est vraiment crado mais ça fonctionne, seulement il n'y avait que peu de lignes à traiter, donc si la vous pouvez m'indiquer une manière plus conventionnel et plus propre ce serait bien.

  8. #8
    Membre expert
    Avatar de sachadee
    Homme Profil pro
    AMI DU BAT
    Inscrit en
    Janvier 2013
    Messages
    1 478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Brésil

    Informations professionnelles :
    Activité : AMI DU BAT
    Secteur : Distribution

    Informations forums :
    Inscription : Janvier 2013
    Messages : 1 478
    Points : 3 768
    Points
    3 768
    Par défaut
    Pour le premier prpblème tu peux skipper les 5 premières lignes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    @echo off
    for /f "skip=5 delims=" %%d in ('type !fichier1!') do Findstr "%%d" fichier2.txt >nul && echo [la ligne %%d existe]>>sortie1.txt || echo [la ligne %%d n'existe pas]>>sortie2.txt
    Pour le 2eme problème donne nous juste un exemple de ton fichier pour pouvoir tester.

    ________________________________
    Un p'tit coup de pouce ça fait toujours plaisir, pensez-y !
    ________________________________

  9. #9
    Membre à l'essai
    Homme Profil pro
    bidouilleur
    Inscrit en
    Novembre 2012
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Novembre 2012
    Messages : 44
    Points : 24
    Points
    24
    Par défaut
    Bien vu je vais tester ça.

    Pour le deuxième problème, ce serait juste pour faire plus propre car la c'est fonctionnel.
    Je dois manipuler les données d'une valeur extraite du registre. Je ne connais pas les données qu'il y a (il n'y en a d'ailleurs souvent aucunes) mais je connais celle que je veux supprimer si elle sont présentes.
    Les données à supprimées sont contenu dans un fichier .txt lu ligne par ligne et comparé aux donnés éventuelles de la valeur du registre que j'ai exportée au préalable.
    Exemple de ligne exportée :

    "une_chaine_quelconque"="C:\\Windows\\fichier.dll C:\\Users\\moi\\AppData\\Local\\Application\\Resources\\autrefichier.dll C:\\Windows\\eventuellement_encore_un_fichier.dll"

    à laquelle je voudrait supprimer C:\\Users\\moi\\AppData\\Local\\Application\\Resources\\autrefichier.dll

    pour donner :

    "une_chaine_quelconque"="C:\\Windows\\fichier.dll C:\\Windows\\eventuellement_encore_un_fichier.dll"

    En sachant que c'est un exemple, s'il n'y a que les données de valeur à supprimer la ligne devrait ressortir comme ceci:

    "une_chaine_quelconque"="" (c'est à dire sans aucunes données pour la valeur)

    Voici comment je procède (je sais c'est crade):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    for /f "tokens=*" %%d in ('type "valeur_exporte.txt"') do ( 
      rem je remplace les \\ par zzzy
      set val=%%d
      set val=!val:\\=zzzy!
      echo !val!>temp.txt
    )
    rem Bon je simplifie mais en gros maintenant je supprime ma ligne (si présente) avec sed (sed "s/!val!//" valeur_exporte.txt>sortie.txt)
    
    rem puis le chemin inverse: je remet les \\ à la place de zzzy
    set var=!var:zzzy=\\!
    
    rem je supprime s'il existe l'espace entre .dll et " (fichier.dll " devient fichier.dll")
    set var=!var: "="!
    
    rem je supprime un des deux espaces s'il y en à deux (si il y a eu une suppression d'un fichier au milieu de la ligne)
    set var=!var:  = !
    
    rem puis je crée le fichier reg à merger...
    echo Windows Registry Editor Version 5.00>fichier.reg
    echo.>>fichier.reg
    echo [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft.....>>fichier.reg
    echo !var!>>fichier.reg
    Voila en gros comment je procède, je sais c'est très très moche mais ça fonctionne.
    Ah et si tu as une petite idée pour ça, je suis surpris de ne pas avoir eu de réponses lister les fichiers recents d'un répertoire, dois-je passer par un vbscript? (je connais encore moins le vb que le batch)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Opération sur un fichier et lecture ligne par ligne
    Par teunniq dans le forum Shell et commandes GNU
    Réponses: 6
    Dernier message: 03/06/2014, 17h57
  2. [Batch] Boucle For pour parser des fichiers + exclusion
    Par L'assembleur dans le forum Scripts/Batch
    Réponses: 2
    Dernier message: 04/07/2011, 15h41
  3. lire fichier .txt (NOTEPAD) ligne par ligne
    Par skambram dans le forum VB.NET
    Réponses: 1
    Dernier message: 06/06/2009, 18h41
  4. lire un fichier de string ligne par ligne
    Par bilzzbenzbilz dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 11/02/2009, 10h44
  5. Réponses: 1
    Dernier message: 18/02/2008, 19h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo