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. 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"
    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??
      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
        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 )
          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 
            
            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??
              1. 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
                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
                  
                  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??!
                2. 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??
                  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
                    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 !??
                      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
                        
                        
                        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)
                          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??
                            1. Salut,

                              perso j'ai rien pigé, précise un peux ,peut être je peux t'aidé .