Batch détecte une modification ds une colone

Résolu
Bonjour,

Je vous explique mon problème, j'ai un fichier .txt contenant ceci:

.
.
.
14/02/2008 20:31 34915 09:41 0501348-1ELE03 0 DCH 10.812 -8.998
14/02/2008 20:32 34957 09:42 0501348-1ELE03 0 DCH 10.798 -8.995
14/02/2008 20:32 34962 09:42 0501348-1ELE03 0 DCH 11.253 -0.003
14/02/2008 20:32 34976 00:00 0501348-1ELE03 0 PAU 11.331 -0.003
14/02/2008 20:33 35035 00:01 0501348-1ELE03 0 PAU 11.421 -0.003
14/02/2008 20:34 35096 00:02 0501348-1ELE03 0 PAU 11.472 -0.002
.
.

Et j'aimerai détecter le changement DCH==>PAU au niveau de la 5eme colonne et lorsque ce changement s'effectue copier la ligne qui précède dans un autre fichier texte, ce qui donnerai ceci:

14/02/2008 20:32 34962 09:42 0501348-1ELE03 0 DCH 11.253 -0.003

Je ne sais pas trop par où commencer, je pense à une boucle for avec tokens=5 mais je n'ai aucune idée pr détecter le changement?? findstr??

Merci d'avance
Configuration: Windows XP
Firefox 3.5.3

17 réponses

  1. Salut,

    perso j'ai rien pigé, précise un peux ,peut être je peux t'aidé .
    0
    1. J'avoue c'est un peu compliqué, en gros pour simplifier j'ai un fichier .txt qui contient ces lignes:

      titi 1
      titi 2
      titi 3
      titi 4
      titi 5
      toto 1
      toto 2
      toto 3
      toto 4

      Et j'aimerai extraire de ce fichier txt la ligne ou s'opère le changement de titi à toto, j'obtiendrai donc ceci dans un autre fichier txt:

      titi 5
      toto 1

      une idée??
      0
      1. Salut,

        J'ai un peu peur que ton besoin dépasse les capacités des commandes batch. Avec une usine à gaz (batch appelant d'autres batch) tu t'approcherais peut-être de la solution...

        Tu vas devoir explorer le scripting de windows (le grand frère de batch en quelque sorte) qui te propose de vraies instructions de manipulation de fichier, celles-là même qui te font défaut. tu pourras programmer en VBScript ou JScript au choix.
        La référence se trouve chez microsoft (ou dans le msdn, je sais plus). je sais juste que tu dois chercher "Scripting" tout simplement et tu devrais rapidement trouver le SCRIPT56.CHM (le guide de programmation)
        0
        1. Contributeur
          j'ai essayé mais je renonce en DOS batch. Si tu veux manipuler des fichiers textes, je te conseille les commandes Unix pour DOS, telles que sed ou gawk ou awk,très puissantes et pas d'installation, juste des .exe. Avec gawk dans UnixUtil.zip/usr/local/wbin/gawk.exe, c'est une ligne pour ton problème.
          https://sourceforge.net/projects/unxutils/files/unxutils/current/
          tutoriel sed sur CCM : https://forums.commentcamarche.net/forum/affich-37620084-sed-introduction-a-sed-part-i
          C:>\ type f2.txt
          titi 1
          titi 2
          titi 3
          titi 4
          titi 5
          toto 1
          toto 2
          toto 3
          toto 4
          C:>\ gawk "{x1[NR]=$0;x2[NR]=$1;if($1!=x2[NR-1] && NR > 1){print x1[NR-1];print $0;exit}}" < f2.tx
          t
          titi 5
          toto 1
          
          C:>\ type f3.txt
          14/02/2008 20:31 34915 09:41 0501348-1ELE03 0 DCH 10.812 -8.998
          14/02/2008 20:32 34957 09:42 0501348-1ELE03 0 DCH 10.798 -8.995
          14/02/2008 20:32 34962 09:42 0501348-1ELE03 0 DCH 11.253 -0.003
          14/02/2008 20:32 34976 00:00 0501348-1ELE03 0 PAU 11.331 -0.003
          14/02/2008 20:33 35035 00:01 0501348-1ELE03 0 PAU 11.421 -0.003
          14/02/2008 20:34 35096 00:02 0501348-1ELE03 0 PAU 11.472 -0.002
          C:>\ 
          C:>\  gawk "{x1[NR]=$0;x2[NR]=$7;if($7!=x2[NR-1] && NR > 1){print x1[NR-1];print $0;exit}}" < f3.tx
          t
          14/02/2008 20:32 34962 09:42 0501348-1ELE03 0 DCH 11.253 -0.003
          14/02/2008 20:32 34976 00:00 0501348-1ELE03 0 PAU 11.331 -0.003
          
          
          0
          1. Ok, je ne savais pas qu'il était possible d'utiliser les commandes Unix sous Windows!
            J'ai essayé quelques commandes et ça marche bien par contre dit moi si je me trompe mais si l'exécutable de la commande (genre: sed.exe) n'est pas dans le répertoire courant cela ne marche pas.
            Ces exécutables ont-ils une place dans l'arborescence de C:\ afin de pouvoir utiliser toutes les commandes UNIX dans n'importe quel répertoire??
            Si c'est faisable je pourrai écrire un .bat qui contiendrai des commandes UNIX !??
            0
            1. Contributeur
              soit le .exe est dans le répertoire, soit on l'exécute avec le chemin \dossier\gawk, soit il est dans n'importe quel répertoire et il faut ajouter ce répertoire dans la variable Path.
              soit dans cmd ou dans le .bat:
              set Path=%Path%;\dossier
              ou bien permanent:
              panneau de config -> système -> avancé -> Variables d'environnements
              0
              1. J'ai rajouté tous les executables dans le Path via le panneau de config et ça fonctionne.

                J'ai donc créé mon .bat avec ceci dedans:

                echo off
                gawk "{x1[NR]=$0;x2[NR]=$1;if($1!=x2[NR-1] && NR > 1){print x1[NR-1];print $0;exit}}" < test.txt >> test2.txt
                exit

                La ligne de code que tu ma faite marche bien mais ne repère qu'un seul changement alors qu'en réalité j'en ai plusieurs à repérer (c'est ma faute je t'ai donné un mauvais exemple):

                titi 1
                titi 2
                titi 3
                titi 4
                titi 5
                toto 1
                toto 2
                toto 3
                toto 4
                tutu1
                tutu2
                tutu3
                tata1
                tata2
                .
                .

                et il me faudrai ceci:
                titi 5
                toto 1
                toto 4
                tutu1
                tutu3
                tata1

                Je ne voit pas trop ce qu'il faut modifier ds la ligne de commande??
                0
                1. Contributeur
                  il suffit d'enlever le ;exit
                  gawk "{x1[NR]=$0;x2[NR]=$1;if($1!=x2[NR-1] && NR > 1){print x1[NR-1];print $0}}"

                  mais il faut que ton exemple soit avec 2 champs séparés
                  titi 1
                  titi 2
                  titi 3
                  titi 4
                  titi 5
                  toto 1
                  toto 2
                  toto 3
                  toto 4
                  tutu 1
                  tutu 2
                  tutu 3
                  tata 1
                  tata 2
                  sinon il faut modifier le code
                  C:>\ gawk "{x1[NR]=$0;x2[NR]=$1;if($1!=x2[NR-1] && NR > 1){print x1[NR-1];print $0}}" < f1.txt
                  titi 5
                  toto 1
                  toto 4
                  tutu 1
                  tutu 3
                  tata 1
                  
                  0
                  1. Ok sans le exit, j'ai une dizaine de champs et cela marche aussi!?
                    Autre question:
                    J'ai plusieurs fichiers contenants des lignes de toto, titi, tata et je voudrai que la commande gawk s'applique pour tt les fichiers du répertoire et m'extraie les résultats dans un document récapitulatif.txt.
                    J'ai essayé ceci dans mon batch mais sans succès:
                    gawk "{x1[NR]=$0;x2[NR]=$1;if($1!=x2[NR-1] && NR > 1){print x1[NR-1];print $0}}" < *.txt >>récapitulatif.txt

                    ça me retourne: syntaxe du nom de fichier ou de volume incorrect??!
                    0
                2. Contributeur
                  essaye sans <
                  gawk ... *.txt >> récapitulatif.txt
                  ou
                  type *.txt | gawk ...>> récapitulatif.txt
                  ou une boucle
                  for %%a in (*.txt) do gawk ... %%a >> récapitulatif.txt
                  0
                  1. Ok, j'opte pour la solution avec la boucle for car j'ai une récurrence a faire sur toute l'arborescence.
                    Pour un dossier cela marche, par contre pour la récurrence j'ai écrit ce script mais ça ne marche pas:

                    echo
                    for %%a in ('dir /b/s *.txt') do (
                    set D=%%~pa
                    gawk "{x1[NR]=$0;x2[NR]=$7;if($7!=x2[NR-1] && NR > 1){print x1[NR-1];print $0}}" "%%a" >> "!D!\recapitulatif.txt"
                    )
                    exit

                    Qu'est-ce qui ne vas pas??
                    0
                    1. Contributeur
                      comme ça
                      @echo off 
                      
                      setlocal enableDelayedExpansion
                      for /f "delims=" %%a in ('dir /b/s *.txt') do (
                      set D=%%~pa
                      gawk "{x1[NR]=$0;x2[NR]=$7;if($7!=x2[NR-1] && NR > 1){print x1[NR-1];print $0}}" "%%a" >> "!D!\recapitulatif.txt"
                      )
                      exit 
                      
                      0
                      1. Le fichier récapitulatif.txt est bien créé dans tous les dossier et sous dossier mais il est vide?! la variable D est donc bien définie, pb au niveau de l'écriture ds le fichier??!

                        A noter que le script précédent marche bien:
                        @echo

                        for %%a in (*.txt) do (
                        gawk "{x1[NR]=$0;x2[NR]=$7;if($7!=x2[NR-1] && NR > 1){print x1[NR-1];print $0}}" %%a >> recapitulatif.txt )
                        0
                        1. Contributeur
                          essayer de mettre un ^ devant ! dans le gawk
                          if($7^!=x2
                          attention, recapitulatif.txt va être pris dans la boucle *.txt !!! essayer une autre extension, recapitulatif.tx2
                          0
                          1. Effectivement recapitulatif.txt est bien pris dans la boucle, j'ai donc rajouté la commande rename (je ne peut pas modifier ttes les extensions a la main) mais sans succès:

                            @echo off

                            setlocal enableDelayedExpansion
                            for /f "delims=" %%a in ('dir /b/s *.txt') do (
                            set D=%%~pa
                            gawk "{x1[NR]=$0;x2[NR]=$7;if($7^!=x2[NR-1] && NR > 1){print x1[NR-1];print $0}}" "%%a" >> "!D!\recapitulatif.tx2"
                            rename "!D!\recapitualtif.tx2 recapitulatif.txt"
                            )

                            syntaxe incorrect est retournée?? faut-il refaire une boucle for pour renommer tous les fichiers??
                            0
                            1. Contributeur
                              pour éviter les problèmes entre les caractères ! ^ > ou autres traités par DOS, même entre ", mettre le code awk dans un fichier:
                              type code.awk
                              {x1[NR]=$0;x2[NR]=$7;if($7!=x2[NR-1] && NR > 1){print x1[NR-1];print $0}}

                              et exécuter
                              gawk -f code.awk "%%a" >> "!D!\recapitulatif.tx2"

                              ton rename est faux : rename "!D!\recapitualtif.tx2" "recapitulatif.txt"
                              0
                              1. Ok, merci du coup de main dubcek!
                                0