Forum Programmation.shell Recherche commande

Posté par  . Licence CC By‑SA.
Étiquettes :
1
21
déc.
2022

Bonjour,

J'ai ce fichier :
XVI 931376 +
XVI 933898 -
XVI 934034 +
XVI 938148 -
XVI 939279 -
XVI 939922 +
XVI 943032 +
XVI 943880 +
XVI 944603 +
XVI 946856 -

J'aimerais créer une variable qui, compte le nombre de "groupements +" de sorte à sortir :
3 (le groupe de 4 plus compte pour 1).

Je recherche sur pleins de forums mais je ne trouve rien…
Merci !

  • # Quel est le besoin ?

    Posté par  . Évalué à 6.

    Pour moi ça ressemble à un exercice …. mais je peux me tromper. Mais que ce soit un exercice ou un réel besoin, avoir un peu de contexte permettrait d'aider plus efficacement : personnellement je peux faire ça avec du shell, la commande awk, dy python/ruby/perl. Je ne passerai peut-être même pas par une comande, mais par plusieurs commandes groupées les unes derriere les autres. Donc donner un peu plus d'infos (sur le cours qui se rapporte à l'exercice ou sur le besoin et le contexte) pourrait permettre de t'aider plus efficacement.

    Voir:
    - https://linuxfr.org/wiki/poser-une-question-oui-mais-quoi-comment
    - https://linuxfr.org/aide#aide-fairemonexercice

    • [^] # Re: Quel est le besoin ?

      Posté par  . Évalué à 4.

      compte créé ce jour-même :-)

    • [^] # Re: Quel est le besoin ?

      Posté par  . Évalué à 5.

      Yep ! Ça ressemble à un exo. Du boulot pour les vacances de noël ?…
      Aller, étudiant inconnu, faut pas lâcher le morceau, ça finira par marcher ! (*)

      Je ferais ça avec awk.
      Pas forcément évident quand on débute, mais ça vaut le coup de s'accrocher. Dans mon cas, j'ai rien compris à cet outil à la fac : c'est quoi ce truc, comment ça marche, ça sert à quoi, la logique est pas logique …
      Mais j'ai eu le déclic quelques années plus tard, et je ne peux plus m'en passer pour plein de choses.
      Dans le cas d'un pote, comment, avec awk, il a mis minable des "p'tits jeunes", le genre capable de faire des batchs journalier en Java et de se plaindre que ça prenait plus de 24h …

      Tout petits conseils : déjà qui dit awk dit regex, forcément, mais vu les critères de comptage, avec des caractères particulier aux regex, y'a du \ dans l'histoire pour commencer. Ensuite, séquence, pas séquence, compteur, toussa quoi !

      (*) selon Frank Lepage, on peut très bien qualifier la démarche de triche par la création d'un compte sur ce site et la demande directe de solution. Ou au contraire, comme une excellente idée de demander à ceux qui savent … Exemple ici, coopération vs compétition …. Je parle de ça parce que je viens de terminer cette vidéo en particulier … Mouais, OK, pas ici, compris, si je veux causer pendant des heures, que j'aille gesticuler ailleurs !

    • [^] # Re: Quel est le besoin ?

      Posté par  . Évalué à 2.

      J'ai une solution one-liner bien dégueulasse à base de sed et grep :-) Ça me rappelle mon collègue (PEB, le clin d'œil si tu nous lis) qui faisait beaucoup de prototyping en shell avec abus de grep et sed. Merci

      • [^] # Re: Quel est le besoin ?

        Posté par  . Évalué à 1. Dernière modification le 21 décembre 2022 à 20:39.

        $ wc soluce
         1 24 97 soluce
        

        1 ligne, 24 mots, 97 caractères

        Qui dit mieux ? (euh moins, more is less)

        • [^] # Re: Quel est le besoin ?

          Posté par  (site web personnel) . Évalué à 2.

          J'ai la flemme d'optimiser…

           1  4 65 soluce
          

          Debian Consultant @ DEBAMAX

          • [^] # Re: Quel est le besoin ?

            Posté par  . Évalué à 1.

            On est d'accord que 65, c'est pour le script awk lui même, sans ", ' ni aucun des appels à cat ou à awk lui-même ?
            J'en suis à 63 alors !

            • [^] # Re: Quel est le besoin ?

              Posté par  (site web personnel) . Évalué à 2.

              C'est l'ensemble sous la forme perl -e 'la-magie', qui est appelé via ./soluce < les-données.

              Pour la peine, je relance d'un :

               1  2 59 soluce2
              

              Debian Consultant @ DEBAMAX

              • [^] # Re: Quel est le besoin ?

                Posté par  (site web personnel) . Évalué à 2.

                Je laisse de côté le -1 trivial (ligne et caractère) en enlevant le caractère retour à la ligne… :)

                Variante awk :

                 1  3 49 awk
                

                Debian Consultant @ DEBAMAX

                • [^] # Re: Quel est le besoin ?

                  Posté par  (site web personnel) . Évalué à 4. Dernière modification le 22 décembre 2022 à 10:30.

                  $ sh soluce < /tmp/exo
                  3
                  $ wc soluce 
                   1  7 31 soluce
                  

                  (avec ?ut ?n?q ?r?p)

                  • [^] # Re: Quel est le besoin ?

                    Posté par  (site web personnel) . Évalué à 3.

                    $ wc soluce2
                    1 4 25 soluce2

                    Les mêmes, mais en utilisant la position fixe.

                  • [^] # Re: Quel est le besoin ?

                    Posté par  (site web personnel) . Évalué à 2.

                    Effectivement, chaîner quelques commandes de base, c'est plus rapide que mes bêtises dans différents langages. Avec une variante de ta méthode :

                     1  5 27 shell
                    

                    Debian Consultant @ DEBAMAX

                    • [^] # Re: Quel est le besoin ?

                      Posté par  . Évalué à 1.

                      Wow ! Chapeau !

                      Bon, après, si ça part dans la magie noire de perl, demain, vous ne pourrez plus comprendre ce que font vos scripts ;-)

                      • [^] # Re: Quel est le besoin ?

                        Posté par  . Évalué à 4.

                        meuh non c'est juste du de cut age, de l' uniq fication un peut de grep, et enfin on on tire la chasse :)

                        Y'a pas de truc mystique ;)

                        Il ne faut pas décorner les boeufs avant d'avoir semé le vent

                    • [^] # Re: Quel est le besoin ?

                      Posté par  . Évalué à 3.

                      25 caractères

                      ./soluce.sh <txt.txt
                      3 3 6
                      indiscret@Fenris:~$ wc soluce.sh
                      1 3 24 soluce.sh

                      je monte a 27 si je veux que le 3 et pas le 3 3 6

                      Il ne faut pas décorner les boeufs avant d'avoir semé le vent

                      • [^] # Re: Quel est le besoin ?

                        Posté par  . Évalué à 1.

                        Yep, je suis à 27 aussi maintenant.

                        Mais on est d'accord que c'est en faisant une méchante supposition sur la taille des lignes ?…

                        • [^] # Re: Quel est le besoin ?

                          Posté par  . Évalué à 3.

                          Mais on est d'accord que c'est en faisant une méchante supposition sur la taille des lignes ?…

                          Complètement :)
                          y'a moyen de ne pas faire cette supposition, mais ça augmente de beaucoup le nombre de caractères

                          Il ne faut pas décorner les boeufs avant d'avoir semé le vent

                          • [^] # Re: Quel est le besoin ?

                            Posté par  . Évalué à 3.

                            en fait pas tant que ça, je ne l'augmente que de 3, mais je fais une supposition sur le fait que c'est le dernier caractère.

                            Il ne faut pas décorner les boeufs avant d'avoir semé le vent

              • [^] # Re: Quel est le besoin ?

                Posté par  . Évalué à 4.

                le miens en fait 10 de moins :p

                1 2 49 sol.sh

                perl -pe'$c+=/\+/&!$b?$b=1:($b=/\+/,0)}{print$c'

                par contre c'est limite de l'invoc cabalistique !

                Il ne faut pas décorner les boeufs avant d'avoir semé le vent

                • [^] # Re: Quel est le besoin ?

                  Posté par  . Évalué à 2.

                  A l'heure ou tout le monde se vante d'avoir la plus grosse, c'est amusant de voir des gens qui cherchent à avoir la plus petite.

                  • [^] # Re: Quel est le besoin ?

                    Posté par  . Évalué à 3.

                    c'est du code golf :)

                    Il ne faut pas décorner les boeufs avant d'avoir semé le vent

                • [^] # Re: Quel est le besoin ?

                  Posté par  . Évalué à 3.

                  bon c'est parti pour l'explication de code ;)

                  déjà on va le segmenter et le commenter

                  # perl -pe c'est plus ou moui l'équivalent de while($_ = <STDIN>)
                  # qu'on peut simplement écrire (while <STDIN>)
                  # ou en plus court (while(<>)
                  # donc on reprend
                  # 
                  #while(<STDIN>) { # pour toute les ligne  pas present (-pe)
                    $c+= # on ajoute à c - bouh c'est pas déclaré par défaut c'est 0
                        (             #je rajoute une parenthèses pour mieux suivre 
                           /\+/       # si y'a un + dans la ligne 
                         &            # bitwise and pour économiser un caractère et pas écrire &&
                         !$b          # not $b ($b représente un état (est-ce que y'avait un + sur la ligne précédente...)
                        ) ?           # donc si l'évaluation de y'a un + et b == false (ou indéfini)
                           $b=1       # $b prend la valeur 1 (et on renvoi 1)
                          : $b=/\+/,0 # $b prend true si y'a un plus, et on renvoi 0... GRUIIIIK
                  #}                  # pas présent fin de la boucle -pe 
                        }{            # définition du bloc END peut aussi s'écrire END{
                        print$c       # on appel print avec comme paramètre $c... aurait du s'écrire print "$c\n";

                  bref à part pour le code golf je déconseille fortement ce code

                  sinon d'un point de vu algorithmique

                  on ajoute 1 au compteur si y'a un + sur la ligne et que sur la ligne précédente y'avait pas de +
                  puis on affiche le compteur.

                  et si on veut faire mois incantation lovecraftienne ça donne a peu près ça (de tête j'ai pas testé)

                  #!/bin/env perl
                  
                  use strict;
                  my $cpt = 0;
                  my $hadPlus = false;
                  while(<>) {
                     if (/\+/) {
                        if (!$hadPlus){
                          $cpt += 1 ;
                          $hadPlus=true;
                        }
                     } else {
                       $hadPlus = false;
                     }
                  }
                  print "$cpt\n"

                  Il ne faut pas décorner les boeufs avant d'avoir semé le vent

                • [^] # Re: Quel est le besoin ?

                  Posté par  . Évalué à 3.

                  perl 5.14 commence à être assez vieux

                  perl -pE'$c+=/\+/&!$b?$b=1:($b=/\+/,0)}{say$c'
                  

                  En bonus on gagne un retour à la ligne qui aide à la lisibilité du résultat.

                  En tout cas chapeau de l'avoir trouvé !

                  https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

        • [^] # Re: Quel est le besoin ?

          Posté par  . Évalué à 1.

          Merci, je connaissais pas wc :)

          J'imagine que tout les jeux de mots ont déjà étés fait 1000 fois, je me lance pas là dedans…

          • [^] # Re: Quel est le besoin ?

            Posté par  . Évalué à 1.

            wc c'est pas une commande à chier. Suggérer wc ainsi, c'était aussi ma façon de donner des indices :-) Le truc pour s'en souvenir "word count"

    • [^] # Re: Quel est le besoin ?

      Posté par  . Évalué à 4.

      Bonjour,

      Tout d'abord merci pour votre réponse.
      Désolé de mon message relativement vague mais en effet je débute en informatique. J'ai suivi des cours sur awk, shell…

      J'ai un projet qui nous demande à partir d'un ficher GTF de levure, de nous "auto-poser" des questions et d'y répondre (ce n'est donc pas du tout guidé comme un exercice).

      Ma question est donc, à partir de l'extrait de fichier que je vous ait soumis, de savoir si deux gènes ($2) d'un chromosome ($1) sont le plus souvent dans le même sens ou dans le sens opposé ($3).

      Je peux vous apporter d'autres informations si nécessaire.
      Encore une fois veillez excuser mon manque de connaissance… bien que je fais de mon mieux !

      En vous remerciant

      • [^] # Re: Quel est le besoin ?

        Posté par  . Évalué à 3.

        Pour répondre à la question d'une potentielle triche, étant donné que ce projet est non guidé et que c'est moi qui ait inventé cette question, si je ne trouve pas la réponse à ma question je me contenterai de passer à une autre ^

        • [^] # Re: Quel est le besoin ?

          Posté par  (site web personnel) . Évalué à 6.

          Mon approche a été :

          1. isoler les +/- (comme $3 ou comme position fixe 12 si les données le permettent ou bien comme dernier caractère). Outils possibles : awk ou cut ou sed…
          2. grouper / fusionner les + ou les - consécutifs. Outils possibles : uniq, …
          3. compter les +. Outils possibles : grep, …
          • [^] # Re: Quel est le besoin ?

            Posté par  . Évalué à 2.

            Super merci, je vais essayer de créer une commande en partant sur cette base.

      • [^] # Re: Quel est le besoin ?

        Posté par  . Évalué à 2.

        Personne ne te reproche ton manque de connaissance. Le plus important c'est de vouloir apprendre. Le truc c'est que parfois certaines personnes abusent de la gentillesse des autres pour leur faire faire leur travail. En général, un peu de contexte aide à guider ceux qui cherchent à apprendre, et permet de filtrer ceux qui ne viennent ici que par paresse.

      • [^] # Re: Quel est le besoin ?

        Posté par  . Évalué à 1.

        Les gens sont chauds, envoie ta solution, et on déballe toutes les nôtres !

        J'ai trop envie de voir les créations de chacun dans le concours au one-liner le plus petit !!

      • [^] # Re: Quel est le besoin ?

        Posté par  . Évalué à 2.

        Le côté intéressant de ta question, c'est que ça permet aussi à ceux qui savent de se lancer des défis comme on a pu le voir dans un des fils de discussion plus haut. Et d'une manière générale, aider des novices est un exerice intéressant (en tout cas pour moi, même si en l'occurence je n'ai pas répondu par manque de temps). Ca permet de se remettre en question.

  • # Noël et solutions !

    Posté par  . Évalué à 1.

    Je vais partager mes soluces à base de commandes shell standards pour Noël, pas de perl, ni de awk pour ma part, mais je serais bien intéresser de voir ça. C'est dommage que je n'ai pas mon horreur initiale sous la main :-D

    Stay tuned

    • [^] # Mes soluces sans perl ni awk, juste des commandes shell de base en pipe

      Posté par  . Évalué à 1. Dernière modification le 26 décembre 2022 à 11:40.

      $ bash soluce1 < f
      3
      $ wc soluce*
        1   5  38 soluce1
        1   8  35 soluce2
        1   5  33 soluce3
        1   5  29 soluce4
        1   7  29 soluce5
        5  30 164 total
      $ grep ^ soluce*
      soluce1:sed -e 's:[^+-]::g'|uniq|grep +|wc -l
      soluce2:cut -d ' ' -f 3|uniq|grep +|wc -l 
      soluce3:sed 's:.* ::'|uniq|grep +|wc -l 
      soluce4:cut -b 12|uniq|grep +|wc -l 
      soluce5:tr -cd [+\\-]|tr - ' '|wc -w
      

      Les solutions 1 à 4 utilise l'enchainement "uniq|grep +|wc -l" pour nettoyer les séries de +, ne garder qu'eux, enfin compter le nombre de lignes. Les commandes d'introduction implémentent différentes hypothèses de substitution de caractères pour ne garder que les + et -.

      Soluce5 est différente et se base sur la commande "tr". Pour la sortie de cette commande il faut compter les mots avec wc : on zappe "uniq" et "grep +". Là j'atteins mes limites et je ne sais pas s'il y a moyen de faire plus court.

      Joyeux Noël !!

  • # awk / uniq / grep / wc

    Posté par  (site web personnel, Mastodon) . Évalué à 2.

    awk '{print $3}'| uniq | grep "+" | wc -l
    

    Sous licence Creative common. Lisez, copiez, modifiez faites en ce que vous voulez.

    • [^] # Re: awk / uniq / grep / wc

      Posté par  (site web personnel, Mastodon) . Évalué à 2. Dernière modification le 26 décembre 2022 à 20:04.

      ou

      awk 'nb=0;old="" $3!=old{nb++; old=$3} end{print("result is "(nb/2))}'

      Sous licence Creative common. Lisez, copiez, modifiez faites en ce que vous voulez.

      • [^] # Re: awk / uniq / grep / wc

        Posté par  . Évalué à 2.

        Chez moi, ça ne semble pas fonctionner du tout avec GNU awk?

        L'une des erreurs évidentes est que end doit être END, mais même ainsi cela donne 0.5. Je rate peut-être une subtilité ceci dit.

        • [^] # Re: awk / uniq / grep / wc

          Posté par  (site web personnel, Mastodon) . Évalué à 1.

          J'avoue, je n'ai pas testé, c'est du pur de tête (je n'ai même pas checker la syntaxe d'ou mon erreur du END).

          Sous licence Creative common. Lisez, copiez, modifiez faites en ce que vous voulez.

    • [^] # Re: awk / uniq / grep / wc

      Posté par  . Évalué à 2. Dernière modification le 27 décembre 2022 à 15:08.

      En pur awk, j'aurai fait: awk '/+{mathjax} / { if(inc==0)++count;inc=1 } /-/{inc=0} END{print count}' mais c'est hyper verbeux (61 caractères, compactable un peu, mais toujours plus de 2 fois plus long que le shell), shell gagne haut la main vu la simplicité du traitement. Je ne sais pas s'il y a plus propre.

      A noter qu'il semble y avoir un bug dans le rendu de linuxfr, donc, voici en moins compact:

      /+$/ {
      if( inc == 0 )
        ++count;
      inc=1
      }
      
      /-$/ {
        inc=0
      }
      END {
        print count
      }
      • [^] # Re: awk / uniq / grep / wc

        Posté par  . Évalué à 2.

        En golfant je peux compacter à 37 caractères cette solution. C'est "mieux", mais clairement moins lisible et toujours plus de 2 fois plus long que la solution shell trouvée: /+/{c+=i?0:1;i=1}/-$/{i=0}END{print c}. En plus, ça fait quand même pas mal de présupposés, genre, un et un seul '+' ou '-' par ligne, toujours en dernier caractère. Vu l'énoncé, ça me semble acceptable ceci dit.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.