.bat incémenter un compteur

Résolu
Bonjour,

J'ai trouvé ce script sur le forum :
In fait en quelque sort un uniq sur le fichier f1.

$ type f1.txt
Group = toto, nom = toto, ville = paris
Group = titi, nom = titi, ville = lille
Group = toto, nom = toto, ville = paris
Group = tata, nom = tata, ville = toulouse

$ type bb.bat
@echo off

copy /Y NUL z1 > NUL
set i=-1
for /f "tokens=4 delims==," %%a in ('type f1.txt') do (
set/a i+=1
echo/%%a >> z1)

set dest=z2
copy /Y NUL %dest% > NUL
for /F %%n in ('type z1') do (
findstr %%n %dest% > NUL
if errorlevel 1 echo %%n >> %dest%)
type z2

Admettons que f1 se transforme en :

$ type f1.txt
Group = toto, nom = toto, ville = paris, voyage=2
Group = titi, nom = titi, ville = lille, voyage=5
Group = toto, nom = toto, ville = paris, voyage=4
Group = tata, nom = tata, ville = toulouse, voyage=3

Comment obtenir ça :

toto 6
titi 5
tata 3

Merci
Configuration: Windows XP
Firefox 3.0.6

24 réponses

Résumé de la discussion

Le besoin est d’agréger des données d’un fichier et de calculer des sommes par groupe avec AWK sous Windows, après transformation du contenu et sommation des champs voyage et quantité. Plusieurs essais préconisent gawk -F[,=] et des expressions comme x[$2] += ($8 + $10) pour cumuler les valeurs par groupe à partir des lignes converties en f3.txt. En pratique, la solution est d’employer gawk.exe plutôt que awk, en définissant le séparateur -F"[,=]" et en accumulant les totaux par nom de groupe. Une précision utile consiste à adapter l’expression pour récupérer voyage et quantite et à tester sur f3.txt afin d’obtenir des résultats comme tata, toto et titi avec les totaux correspondants.

Bobot (l’IA à votre service)
  1. Contributeur
    hello
    c'est un peu lourd en DOS, avec awk, outil bien connu sur Unix et qui se trouve ICI dans usr/local/wbin/awk.exe
    il suffit de:
    $ type f3.txt
    Group = toto, nom = toto, ville = paris, voyage=2
    Group = titi, nom = titi, ville = lille, voyage=5
    Group = toto, nom = toto, ville = paris, voyage=4
    Group = tata, nom = tata, ville = toulouse, voyage=3
    
    $ awk -F"[,=]" "{x[$2] += $NF} ; END {for (n in x) print n, x[n]}" < f3.txt
     tata 3
     toto 6
     titi 5
    
    0
    1. Oui c'est lourd en dos mais en fait c'est pour une machine sous windows.
      0
      1. Contributeur
        oui mais le awk que j'utilise et qui est dans le .zip est pour DOS
        $ awk --version
        GNU Awk 3.1.6
        ...
        $ ver
        Microsoft Windows XP [version 5.1.2600]
        0
        1. Sur ton lien il y a 2 zip.
          c'est dans le UnxUtilsSrc ou UnxUtils ?
          Dans le UnxUtilsSrv j'ai un dossier gawk-3.0.4 avec plein de fichier et dossier dedans je fais quoi pour avoir la commande de dispo sur mon pc.
          Dans le UnxUtils sous ...\UnxUtils\usr\local\wbin j'ai un fichier gawk quand je l'execute il y a une fenêtre dos qui s'ouvre pendant une demi seconde et voila rien de plus :/ Comment je fais pour avoir ensuite la commande awk ?
          0
          1. Contributeur
            pardon je me suis trompé
            UnxUtilsSrc.zip c'est le code source des commandes
            il faut prendre gawk.exe et dans la commande que j'ai mis plus haut tu utilses gawk au lieu de awk
            0
            1. Mais je le trouve ou le gawk.exe ? Et je le copie ou ? (car je n'ai pas de dossier commande dans windows)
              0
              1. Contributeur
                tu télécharges UnxUtils.zip
                dans ce fichier zip, tu vas dans usr -> local -> wbin
                tu copies gawk.exe soit dans le dossier où tu l'exécutes, soit dans un dossier dans le PATH, \windows\system32 par exemple
                pour afficher PATH : echo %PATH%
                0
                1. Ok merci.
                  Du coup j'ai testé ta ligne de commande et ça fonctionne niquel.
                  J'essaye de bien comprendre la commande tapé et je me pose une question :
                  Je suppose que c'est ce qu'il y a derrière le end qui fait que l'on compte.
                  Cependant admettons qu'on est autre chose derrière ou même autre chose à compter du genre :

                  $ type f3.txt
                  Group = toto, nom = toto, ville = paris, voyage=2, quantite=5, type=masculin
                  Group = titi, nom = titi, ville = lille, voyage=5, quantite=3, type=feminin
                  Group = toto, nom = toto, ville = paris, voyage=4, quantite=4, type=masculin
                  Group = tata, nom = tata, ville = toulouse, voyage=3, quantite=7, type=masculin

                  Du coup on ne peut plus utiliser le end.
                  De plus, comment je peux ajouter des mots du genre :
                  tata a voyage 3 fois
                  toto a voyage 6 fois
                  titi a voyage 5 fois
                  0
                  1. Contributeur
                    gawk -F"[,=]" "{x[$2] += $NF} ; END {for (n in x) print n, x[n]}"
                    NF c'est le dernier champ que l'on aditionne avec += donc c'est fait pour une valeur numérique, mais on peut changer le code pour compter des mots
                    pour sommer voyage= il ne faut plus utiliser NF mais $8 le huitème champ
                    gawk -F"[,=]" "{x[$2] += $8} ; END {for (n in x) print n, x[n]}"
                    0
                    1. Du coup j'ai essayé pour la petite modification avec mon post 11 :

                      tata 10
                      toto 15
                      titi 8

                      avec ça :
                      gawk -F"[,=]" "{x[$4] += $8 +=$10} ; END {for (n in x) print n, x[n]}" < f3.txt

                      Du coup il additionne $8 et $10 au lieu de commencer un nouveau comptage :/
                      0
                      1. Contributeur
                        tu veux additionner voyage et quantité ?
                        tu peux ajouter des mots à afficher
                        print n, "a voyagé", x[n], "fois"}"
                        0
                        1. gawk -F"[,=]" "{x[$2] += $8} ; END {for (n in x) print n, "a voyage", x[n], "fois"}" < f3.txt

                          J'obtiens 2 erreurs :

                          gawk: cmd. line:2: (END OF FILE)
                          gawk: cmd. line:2: parse error
                          0
                        2. Contributeur
                          @kimojooui, j'ai oublié, il faut protéger les " avec \ parce qu'on est à l'intérieur de "
                          print n, \"a voyage\", x[n], \"fois\"}"
                          0
                        3. @dubcekok merci ça marche niquel.

                          Et pour avoir voyage et quantite (post 14)?
                          0
                      2. Non je ne veut pas ajouter voyage et quantite mais avec la commande du post 12 ça ajoute :/
                        Du coup je cherche la bonne commande pour avoir ça :

                        tata 3 7
                        toto 6 9
                        titi 5 3

                        mais ma commande me donne ça :

                        tata 10
                        toto 15
                        titi 8

                        gawk -F"[,=]" "{x[$2] += $8 += $10} ; END {for (n in x) print n, x[n]}" < f3.txt
                        ou
                        gawk -F"[,=]" "{x[$2] += $8 += $10} ; END {for (n in x) print n, x[n], y[n]}" < f3.txt
                        donne le même résultat au dessus.
                        0
                        1. Contributeur
                          soit x[$2] += $8 += $10
                          soit x[$2] += ($8 + $10)
                          0
                          1. gawk -F"[,=]" "{x[$2] += $8 += $10} ; END {for (n in x) print n, x[n]}" < f3.txt
                            gawk -F"[,=]" "{x[$2] +=( $8 + $10)} ; END {for (n in x) print n, x[n]}" < f3.txt

                            avec ces 2 commandes :
                            tata 10
                            toto 15
                            titi 8

                            Après j'ai essayé un peu tout et n'importe quoi :
                            gawk -F"[,=]" "{x[$2] +=( $8 + $10)} ; END {for (n in x,y) print n, x[n], y[n]}" < f3.txt
                            ... Et tout les dérivés :)
                            Mais je n'obtiens que des erreurs.

                            gawk -F"[,=]" "{x[$4] += $8} ; gawk -F"[,=]" "{x[$4] += $10} ;END {for (n in x,y) print n, x[n], y[n]}" < f3.txt
                            De même erreur :/
                            0
                            1. Contributeur
                              ce n'est pas comme DOS qui ajoute de s variables, que veux tu dans y ?
                              la somme du champs 10 ?
                              gawk -F"[,=]" "{x[$2] += $8 ; y[$2] += $10} ; END {for (n in x) print n, x[n], y[n]}" < f3.txt
                              0
                              1. Je n'étais pas si loin que ça :)
                                Du coup j'ai une autre idée :)

                                $ type f3.txt
                                Group = toto, nom = toto, ville = paris, voyage=2, temps=1h:23m:11s, quantite=5, type=masculin
                                Group = titi, nom = titi, ville = lille, voyage=5, temps=2h:07m:50s, quantite=3, type=feminin
                                Group = toto, nom = toto, ville = paris, voyage=4, temps=3h:45m:58s,quantite=4, type=masculin
                                Group = tata, nom = tata, ville = toulouse, voyage=3, temps=4h:16m:11s, quantite=7, type=masculin

                                Pour le début je vais mettre gawk -F"[,=:], ça changera du coup la position des autres champs pour la commande mais c'est gèrable. Par contre pour les heures minutes pour que le comptage fonctionne il faut virer les caractères h m s. En plus il faut que si les secondes et les minutes dépassent 60, il faut que ça incrémente la valeur au dessus.

                                Après j'arrête de t'embéter :)
                                0
                                1. Contributeur
                                  quand le code devient compliqué, c'est plus pratique de le mettre dans un fichier que sur la ligne de commande.
                                  split éclate le champ 10 dans le tableau t en séparant avec les caractères hms: et il place les heures dans t[1], les minutes dans t[3] et les secondes dans t[5], on les somme dans des tableaux h, m, et s.
                                  à la fin, après le END, on divise les secondes par 60 qu'on ajoute aux minutes, on divise les minutes par 60 qu'on ajoute aux heures et on garde le reste de la division (modulo, le %) pour afficher les secondes et minutes
                                  $ type f3.txt
                                  Group = toto, nom = toto, ville = paris, voyage=2, temps=1h:23m:11s, quantite=5, type=masculin
                                  Group = titi, nom = titi, ville = lille, voyage=5, temps=2h:07m:50s, quantite=3, type=feminin
                                  Group = toto, nom = toto, ville = paris, voyage=4, temps=3h:45m:58s,quantite=4, type=masculin
                                  Group = tata, nom = tata, ville = toulouse, voyage=3, temps=4h:16m:11s, quantite=7, type=masculin
                                  
                                  $ gawk -F"[,=]" -f f1.awk < f3.txt
                                   tata 4h 16m 11s
                                   toto 5h 9m 9s
                                   titi 2h 7m 50s
                                  
                                  $ type f1.awk
                                  {x[$2]+=$8 ; split($10,t,"[hms:]"); h[$2]+=t[1];m[$2]+=t[3];s[$2]+=t[5]} ;
                                  END {for (n in x) { s1=s[n]%60 ; s2=int(s[n]/60); m1=(m[n]+s2)%60;m2=int((m[n]+s2)/60);h1=h[n]+m2;
                                   print n, h1"h",m1"m",s1"s"}}
                                  
                                  0
                                  1. Ok merci

                                    J'ai essayé une petite modifications mais je ne comprends pas pourquoi ça ne fonctionne pas.

                                    $ type f3.txt
                                    Group = toto, nom = toto, ville = paris, voyage:2, temps=1h:23m:11s, quantite:5, type=masculin
                                    Group = titi, nom = titi, ville = lille, voyage:5, temps=2h:07m:50s, quantite:3, type=feminin
                                    Group = toto, nom = toto, ville = paris, voyage:4, temps=3h:45m:58s,quantite:4, type=masculin
                                    Group = tata, nom = tata, ville = toulouse, voyage:3, temps=4h:16m:11s, quantite:7, type=masculin

                                    $ type f4.awk
                                    {x[$4]+=$8; y[$4]+=$14; split($10,t,"[h]"); split($11,t,"[m]"); split($12,t,"[s]"); h[$4]+=t[1];m[$4]+=t[3];s[$4]+=t[5]} ;
                                    END {for (n in x) { s1=s[n]%60 ; s2=int(s[n]/60); m1=(m[n]+s2)%60;m2=int((m[n]+s2)/60);h1=h[n]+m2;
                                    print n, x[n], y[n], h1"h",m1"m",s1"s"}}

                                    $ gawk -F"[,=:]" -f f4.awk < f3.txt

                                    tata 3 7 11h 0m 0s
                                    toto 6 9 69h 0m 0s
                                    titi 5 3 50h 0m 0s

                                    En gros j'ai remplacer certains = par des :. Du coup voyage et quantite fonctionnent bien mais pour le temps je ne vois pas pourquoi ça ne fonctionne pas.
                                    0
                                    • 1
                                    • 2