Tri des lignes d'un fichier

Résolu
Bonjour,

Je voudrais savoir s'il est possible avec sed (ou awk ou sort) de trier un fichier (selon divers critères de tri) contenant plusieurs lignes représentant chacune un fichier.

Par exemple, prenons le fichier cosmos.txt (obtenu avec ls -gGt) qui contient les lignes suivantes :

total 31664

-rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg

-rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[739x600]1996.jpg

-rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x601]1998.jpg

-rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[603x600]1997.jpg

-rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[1280x1280]1999.jpg

-rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x601]1999.jpg


Premierement, il faudrait eliminer la premiere ligne (total 31664). Ca devrait pas poser de problemes avec : sed '1d'

Dans mon fichier, j'ai 6 champs.

Je voudrais trier mon fichier selon le sixieme champ, soit le nom des fichiers.

De plus, je voudrais que le premier critère de tri soit le premier nombre (plus petit) associé à la résolution (compris entre [ et x ).

Le deuxième critère serait ensuite le second nombre associé à la résolution (compris entre x et ] ).

Mon dernier critère serait ensuite l'année (compris entre ] et . ).

Le résultat final désiré est le suivant :

-rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg

-rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x601]1998.jpg

-rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x601]1999.jpg

-rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[603x600]1997.jpg

-rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[739x600]1996.jpg

-rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[1280x1280]1999.jpg


C'est ca mon petit probleme ... Ca me serait tres utile de trier mes fichiers selon les criteres de mon choix. Ici, j'en ai mis trois. Mais ca pourrait etre deux, cinq, etc...

Merci beaucoup,
Configuration: Linux
Konqueror 3.5

28 réponses

Résumé de la discussion

On cherche à trier un fichier où chaque ligne décrit un fichier image, selon des critères multiples comme le nom, la résolution et l'année, dans un ordre personnalisé. Plusieurs scripts, majoritairement en Perl, et des approches sed/awk/sort, proposent d'extraire les valeurs entre crochets et les années, puis de trier selon ces critères dans l'ordre de priorité. Détail de l'exemple : suppression de la première ligne, tri selon le premier nombre de résolution, puis le second et enfin l'année, avec des résultats dépendant de l'ordre d'exécution des transformations. En pratique, les échanges confirment que le troisième critère est l'année et montrent que le tri peut s'adapter au nombre de critères souhaité, avec des tests comparant différentes séries d'extractions et d'ordres.

Bobot (l’IA à votre service)
  1. Modérateur
    Salut,

    Dans mon fichier, j'ai 6 champs.
    je ne vois que 5

    Mais ca pourrait etre deux, cinq, etc...
    je pense que tu dois être plus précis.

    Et avec perl ça ne te conviens pas?
    Si oui mets ton fichier cosmos.txt sur cjoint.com
    0
    1. Salut lami20j,

      Concernant le nombre de champs :

      1) les droits
      2) colonne ou c'est indique 1
      3) taille des fichiers
      4) date
      5) heure
      6) nom du fichier

      A moins que la date et l'heure concerne la meme donnee ...

      Dans l'exemple que j'ai donne, j'ai choisi trois criteres de tri, soit la valeur de la resolution horizontale, la valeur de la resolution verticale et l'annee.

      J'aurais pu laisser tomber l'annee et je me serais ramasser avec deux criteres. Dans un autre type de fichier, ogg par exemple, je peux ajouter d'autres caracteristiques : langue, nationalite, nom de l'artiste, l'annee, bitrate, duree, etc ...

      a_gbr_gentle_giant_-_who_do_you_think_you_are[1977]160.ogg

      a_ : chanson anglaise (f=francais,g=allemand)
      gbr_: groupe qui vient de la grande-Bretagne (fra=France usa=Etats-Unis)
      _-_xxxxxxxx : titre
      [1977] : annee
      160 : bitrate

      De cette facon, je peux classer dans un fichier les chansons selon le type et le nombre de criteres que je desire. Meme principe pour les images.

      Concernant Perl je ne le connais pas mais ca ne me derange pas de l'utiliser. Je ne sais meme pas si Perl vient avec Edgy Eft. Mais je sais que sedet awk sont assez puissants pour faire ce genre de travail. J'aimerais me concentrer sur ces deux editeurs et ne pas m'etendre trop ...

      Merci de ton aide
      0
      1. Modérateur
        Salut,

        Je ne sais meme pas si Perl vient avec Edgy Eft.
        Ha!Ha!Ha!

        essaie de supprimer Perl depuis ton système et tu verras que tu devras recommencer l'installation ou presque.

        Perl se trouve sur tout système GNU/Linux.
        A vrai dire il est né du sed et awk à cause de certains limites. En Perl il n'y a pas des limites inutiles ;-)

        Pour ce qui et du sed et awk ce n'est pas vraiment mon point fort.
        0
        1. Je viens de faire man perl et effectivement Perl est bien installe aur ma machine. Il donne des sites a la fin.

          Mais est-ce qu'il est possible de faire apparaitre les guides suivants (parmi les autres indiques dans man) a partir d'une commande.

          perlintro Perl introduction for beginners
          perltoc Perl documentation table of contents

          merci
          0
          1. Modérateur
            ici la documentation en français http://perl.mines-albi.fr/
            si l'anglais ne te pose pas de problèmes alors tu peux faire
            man perlintro
            man perltoc


            Voici un petit exemple, tu enregistres dans un fichier tri.pl et tu le lances avec perl tri.pl
            #!/usr/bin/perl
            #
            while(<DATA>){
                    s/ /=/g;
                    s/\[/;/g;
                    s/\]/,/g;
                    s/(\d+)x(\d+)/$1#$2/g;
                    push @nontrie,$_;
            }
            
            @trie = map {$_->[0] }
                    sort {
                          $a->[0] <=> $b->[0]
                                  ||
                          $a->[1] <=> $b->[1]
                                  ||
                          $a->[2] cmp $b->[2]
                    } map { [ $_, (split /[=;,#]/)[6..8] ] } @nontrie;
            
            map { s/=/ /g;s/;/[/g;s/,/]/g;s/#/x/g; } @trie;
            print @trie;
            __END__
            -rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg
            -rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[739x600]1996.jpg
            -rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x601]1998.jpg
            -rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[603x600]1997.jpg
            -rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[1280x1280]1999.jpg
            -rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x601]1999.jpg
            
            voici le résultat
            lami20j@debian:~/trash$ perl artagon
            -rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg
            -rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x601]1998.jpg
            -rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x601]1999.jpg
            -rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[603x600]1997.jpg
            -rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[739x600]1996.jpg
            -rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[1280x1280]1999.jpg
            

            0
            1. Donc, tu as reussi a trie les lignes!

              Mais tu ne sembles pas utilise de fichier comme input a ton programme. Tu mets plutot tes donnees initiales a la fin de ton programme
              (apres __END__). Je vais etudier to programme qui m'apparait comme du chinois.

              J'ai essaye de faire man perlintro et man perltoc ma ca me dit qu'il n'a pas de manuel.

              $ man perlintro
              No manual entry for perlintro


              Je vais lire la page man de Perl et je vais aller lire sur le site officiel de Perl avant de revenir sur CCM.

              Pour le moment, merci encore lami20j.
              0
              1. Modérateur
                Donc, tu as reussi a trie les lignes!
                je n'avais pas le choix :-))

                Mais tu ne sembles pas utilise de fichier comme input a ton programme. Tu mets plutot tes donnees initiales a la fin de ton programme

                exactement, c'est juste un test, puisque je n'ai pas le fichier en totalité

                qui m'apparait comme du chinois.
                Non, c'est du Kanji ;-DD

                $ man perlintro
                No manual entry for perlintro


                il faut installer la doc du perl
                sudo aptitude install perl-doc
                0
                1. Salut lami20j,

                  J'ai essayé ton programme et il y a quelque chose que je ne comprend pas. J'ai fait des tests. Le résultat du tri dépend de l'ordre des lignes. En principe, ca ne devrait pas être le cas.

                  Test 1 – Mis la troisième ligne à la fin dans le deuxième essai.

                  Essai #1

                  Données :

                  -rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg
                  -rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[739x600]1996.jpg
                  -rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x601]1998.jpg
                  -rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[603x600]1997.jpg
                  -rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[1280x1280]1999.jpg
                  -rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x601]1997.jpg

                  Résultat

                  -rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg
                  -rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x601]1998.jpg
                  -rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x601]1997.jpg
                  -rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[603x600]1997.jpg
                  -rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[739x600]1996.jpg
                  -rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[1280x1280]1999.jpg

                  Essai #2

                  Maintenant, si je mets la ligne 3 à la fin, i.e. :

                  Données

                  -rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg
                  -rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[739x600]1996.jpg
                  -rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[603x600]1997.jpg
                  -rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[1280x1280]1999.jpg
                  -rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x601]1997.jpg
                  -rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x601]1998.jpg

                  Résultat

                  -rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg
                  -rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x601]1997.jpg
                  -rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x601]1998.jpg
                  -rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[603x600]1997.jpg
                  -rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[739x600]1996.jpg
                  -rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[1280x1280]1999.jpg

                  Donc, on voit que le résultat n'est pas le même. Toutefois, on remarque qu'il tri bel et bien en fonction des deux résolutions. Mais quel est le troisième critère de tri?

                  Test 2 – Mis la même résolution partout et interchangé les lignes

                  Essai #1

                  Données

                  -rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg
                  -rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[600x600]1996.jpg
                  -rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x600]1998.jpg
                  -rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[600x600]1997.jpg
                  -rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[600x600]1999.jpg
                  -rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x600]1997.jpg

                  Résultat

                  -rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg
                  -rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[600x600]1996.jpg
                  -rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x600]1998.jpg
                  -rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[600x600]1997.jpg
                  -rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[600x600]1999.jpg
                  -rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x600]1997.jpg

                  Essai #2

                  Données

                  -rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[600x600]1999.jpg
                  -rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[600x600]1996.jpg
                  -rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg
                  -rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[600x600]1997.jpg
                  -rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x600]1997.jpg
                  -rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x600]1998.jpg


                  Résultat

                  -rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[600x600]1999.jpg
                  -rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[600x600]1996.jpg
                  -rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg
                  -rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[600x600]1997.jpg
                  -rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x600]1997.jpg
                  -rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x600]1998.jpg


                  Donc, on voit que le script n'a pas changé l'ordre des lignes dans les deux cas. Je crois qu'il n'y a pas trois critères de tri dans ce programme mais deux seulement.

                  J'aurais plusieurs autres questions mais le message va etre trop long!!! A la prochaine.

                  Salutations,
                  0
                  1. Modérateur
                    Salut,

                    si tu te rappelles bien j'ai dit ça exactement, c'est juste un test, puisque je n'ai pas le fichier en totalité

                    Mais quel est le troisième critère de tri?
                    c'est à toi de me le dire ;-)

                    envoie ton fichier par mail (tu trouveras mon mail dans mon profil ;-)
                    0
                    1. Salut lami20j,

                      Si tu relis mon premier message tu vas remarquer que j'avais spécifié que mon troisième critère était l'année.

                      Quant au fichier dont tu parles en question, j'en ai pas un vrai spécifiquement. C'est juste pour faire des tests. Par la suite, je vais appliquer ton script à mes répertoires pour le vrai et ça va me être très utile.

                      Mais tu me fais soulever une question. Dans ton exemple, tu as mis les données à la fin de ton programme Perl. Comme tu l'as écrit, tu aurais pu mettre tes données dans un fichier que tu aurais pu appeler à partir de la ligne de commande.
                      Maintenant, je suis curieux de savoir si tu aurais pu "tuyauter" une commande ls vers ton script Perl, genre :

                      ls -gG * | perl tri.pl

                      Ainsi, ça me permettrait de savoir l'allure du tri directement à l'écran avant de l'envoyer dans un fichier.

                      Merci, ;)
                      0
                      1. Modérateur
                        Re,

                        Voilà,
                        #!/usr/bin/perl
                        #
                        while(<>){
                                s/ /=/g;
                                s/\[/;/g;
                                s/\]/,/g;
                                s/(\d+)x(\d+)/$1#$2/g;
                                push @nontrie,$_;
                        }
                        
                        @trie = map {$_->[0] }
                                sort {
                                      $a->[0] <=> $b->[0]
                                              ||
                                      $a->[1] <=> $b->[1]
                                              ||
                                      $a->[2] cmp $b->[2]
                                } map { [ $_, (split /[=;,#]/)[6..8] ] } @nontrie;
                        
                        map { s/=/ /g;s/;/[/g;s/,/]/g;s/#/x/g; } @trie;
                        print @trie;
                        __END__
                        Maintenant tu peux exécuter avec ta commande.
                        A savoir que le problème c'est a cause du nombre de champs. J'ai l'impression que tu n'as pas toujours le même nombre de champs par ligne, il faut trouver un moyen d'avoir le même nombre de colonnes (le même nombre de séparateurs) pour chaque ligne.
                        Ca j'ai remarqué quand j'ai fait les tests.
                        0
                        1. lami20j, je ne suis pas sur de te bien te comprendre ici.

                          Tu veux possiblement dire qu'un script donné correspond uniquement à une commande spécifique. Par exemple, si je fais ls -gG ca correspondra a un script. Si je fais ls -l, je devrai modifier le script.

                          Cette semaine j'ai modifié ton programme en exécutant la première partie seulement, pour savoir ce qu'elle faisait :

                          #!/usr/bin/perl
                          #
                          while(<DATA>){
                          s/ /=/g;
                          s/\[/;/g;
                          s/\]/,/g;
                          s/(\d+)x(\d+)/$1#$2/g;
                          push @nontrie,$_;
                          }
                          print @nontrie;
                          __END__
                          -rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg
                          -rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[739x600]1996.jpg
                          -rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x601]1998.jpg
                          -rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[603x600]1997.jpg
                          -rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[1280x1280]1999.jpg
                          -rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x601]1999.jpg

                          Cela a eu pour effet de remplacer les espacements par le signe "=" [ par ; ] par ,et x par #.

                          Je croyais au début que tu voulais créer, de cette façon, un seul champ. Est-ce le cas, ou bien est-ce que tu entres de nouveaux délimiteurs (ou séparateurs de champs)? Si c'est le cas, pourquoi changer? (Je comprends pour l'espacement mais pas pour les autres).

                          Merci
                          0
                          1. Modérateur
                            C'est très rare quand j'écrit un code de la même façon.
                            Je me rends compte que le 1ère fois je me suis compliqué, mais je l'ai fait rapide sans réfléchir trop.
                            Voici un code qui est bien plus simple que le 1er et j'espère qu'il couvrira toutes les situations

                            1 teste ce script avec l'ajout de ton fichier après __END__
                            #!/usr/bin/perl
                            
                            while(<DATA>){
                              /.*:\d+\s+(.*)\[(\d+)x(\d+)\](\d{4})\..*/;
                              chomp;
                              push @nontrie,[$_,$2,$3,$4];
                            }
                            
                            
                            @trie = map {$_->[0] }
                                    sort {
                                          $a->[1] <=> $b->[1]
                                                  ||
                                          $a->[2] <=> $b->[2]
                                                  ||
                                          $a->[3] <=> $b->[3]
                                    } @nontrie;
                            
                            print "$_\n" for @trie;
                            __END__
                            
                            


                            2. pour tester avec la commande ls -gG * | perl tri.pl utilise ce script
                            tu remarqueras qu'au lieu de <DATA> j'utilise l'opérateur <> sans rien à l'intérieur (cet opérateur s'appelle opérateur diamant ;-) à cause de la forme (en fait Larry Wall ne trouvait pas un nom pour cet opérateur et c'est sa petite fille qui a dit "it's like a diamant - voilà pour la petite histoire ;-)
                            #!/usr/bin/perl
                            
                            while(<>){
                              /.*:\d+\s+(.*)\[(\d+)x(\d+)\](\d{4})\..*/;
                              chomp;
                              push @nontrie,[$_,$2,$3,$4];
                            }
                            
                            
                            @trie = map {$_->[0] }
                                    sort {
                                          $a->[1] <=> $b->[1]
                                                  ||
                                          $a->[2] <=> $b->[2]
                                                  ||
                                          $a->[3] <=> $b->[3]
                                    } @nontrie;
                            
                            print "$_\n" for @trie;
                            __END__
                            

                            0
                            1. Salut,

                              C'est très rare quand j'écrit un code de la même façon.

                              et c'est surtout vrai avec Perl ! :-)

                              :-))
                              0
                              1. Bonjour lami20j,

                                J'ai essayé ton deuxième script. Cette fois-ci, il fonctionne selon les critères que j'avais donnés. Je n'ai pas réussi à le prendre en défaut!!!

                                Quant à ton troisième script (en ligne de commande) il fonctionne bien mais il tri à l'inverse. Pourtant, il est similaire au deuxième??? Il devrait trier dans le meme sens!!! Mais ce n'est pas si grave. L'important c'est que tu as reussi a le faire fonctionner independamment des options : je l'ai fait fonctionner avec ls -l et ls -gG sans problemes.

                                Pour le moment, j'aimerais, si tu permets, revenir sur ton premier script (j'ai passé suffisamment de temps à l'étudier, je ne veux pas m'en débarasser immèdiatement!!!). Même si tu sembles le renier ;-) , je le trouve très intéressant car il y a beaucoup d'éléments du langage que je voudrais approfondir du fait que je veux commencer à étudier Perl. Mon but n'est pas uniquement d'obtenir des scripts qui fonctionnent bien mais je veux également les comprendre!!! Je le remets donc ici :

                                Premier script

                                #!/usr/bin/perl
                                #
                                while(<DATA>){
                                s/ /=/g;
                                s/\[/;/g;
                                s/\]/,/g;
                                s/(\d+)x(\d+)/$1#$2/g;
                                push @nontrie,$_;
                                }

                                @trie = map {$_->[0] }
                                sort {
                                $a->[0] <=> $b->[0]
                                ||
                                $a->[1] <=> $b->[1]
                                ||
                                $a->[2] cmp $b->[2]
                                } map { [ $_, (split /[=;,#]/)[6..8] ] } @nontrie;

                                map { s/=/ /g;s/;/[/g;s/,/]/g;s/#/x/g; } @trie;
                                print @trie;

                                __END__
                                -rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg
                                -rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[739x600]1996.jpg
                                -rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x601]1998.jpg
                                -rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[603x600]1997.jpg
                                -rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[1280x1280]1999.jpg
                                -rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x601]1999.jpg


                                J'aurais deux questions :

                                Question 1 - Dans ton premier message, tu suggérais qu'il y avait 5 champs dans chaque ligne de données. Moi, j'en avais calculé 6. Est-ce que nous avons 5 ou 6 champs dans le fichier initial?
                                (A cause du 6 dans la ligne map { [ $_, (split /[=;,#]/)[6..8] ] } @nontrie; je crois que tu
                                considères qu'il y en a 6.)

                                Question 2 - Encore par rapport à la même section :

                                @trie = map {$_->[0] }
                                sort {
                                $a->[0] <=> $b->[0]
                                ||
                                $a->[1] <=> $b->[1]
                                ||
                                $a->[2] cmp $b->[2]
                                } map { [ $_, (split /[=;,#]/)[6..8] ] } @nontrie
                                ;

                                Quelle est la séquence d'exécution des commandes? Est-ce que Perl exécute les blocs selon la séquence 1 ou 2?

                                Séquence 1

                                1) map { [ $_, (split /[=;,#]/)[6..8] ] } @nontrie;
                                2) sort {
                                $a->[0] <=> $b->[0]
                                ||
                                $a->[1] <=> $b->[1]
                                ||
                                $a->[2] cmp $b->[2]
                                }
                                3) map {$_->[0] }


                                ou selon la séquence inverse :

                                Séquence 2

                                1) map {$_->[0] }
                                2) sort {
                                $a->[0] <=> $b->[0]
                                ||
                                $a->[1] <=> $b->[1]
                                ||
                                $a->[2] cmp $b->[2]
                                }
                                3) map { [ $_, (split /[=;,#]/)[6..8] ] } @nontrie;


                                Moi, je crois que c'est la séquence 1 (il doit "splitter" les données avant de les trier.)

                                Note : J'ai téléchargé le document Une compilation en PDF de la documentation Perl (5.8.5) présente sur le site http://perl.enstimac.fr/ que tu m'avais proposé antérieurement. Ca fait en tout 1714 pages!!! Ouais!
                                J'ai lu la page man perlintro. C'est une bonne introduction mais ce n'est pas au niveau de difficulté de ton premier script.

                                Merci lami20j
                                0
                                1. Modérateur
                                  Salut,

                                  oublie le 1er script, j'ai mail interprété les champs, et comme un con j'ai créer moi même les séparateus ;-))

                                  oui c'est bien la séquence 1

                                  Voici le code écrit dans une présentation plus lisible

                                  Quant à ton troisième script (en ligne de commande) il fonctionne bien mais il tri à l'inverse. Pourtant, il est similaire au deuxième??? ;
                                  Je viens de me rendre compte que j'ai oublié une chose ;-)) Ca doit être à cause de la paresse

                                  En fait l'alog correct c'est celui là
                                  #!/usr/bin/perl
                                  
                                  while(<DATA>){
                                    /.*:\d+\s+(.*)\[(\d+)x(\d+)\](\d{4})\..*/;
                                    chomp;
                                    push @nontrie,[$_,$2,$3,$4];
                                  }
                                  
                                  
                                  @trie = map {$_->[0]}
                                          sort {
                                                $a->[1] <=> $b->[1]
                                                        ||
                                                $a->[2] <=> $b->[2]
                                                        ||
                                                $a->[3] <=> $b->[3]
                                          }
                                          map { $_ } @nontrie;
                                  
                                  print "$_\n" for @trie;
                                  
                                  pour la ligne de commande enlève DATA

                                  Et voici la répresentation visible
                                  L'algorithme s'exécute dans l'ordre inverse comme tu l'as bien remarqué

                                  Etape 1
                                  - pas vraiement necessaire
                                  toutefois pour mettre en evidence l'algorithme de Randal Scwartz appellé map-sort-map
                                  Le tableau @nontrie contient plusieurs tableau anonymes dont 4 champs chacun
                                  1er champ c'est la ligne obtenu avec ls
                                  2,3 et 4 sont les critères de tri
                                  @tmp = map { $_ } @nontrie; # chaque élément de @nontrie c'est un tableau anonyme
                                  Etape2

                                  Ici le table @tmp est trié selon 3 critère
                                  2 , 3 et 4 ème champ (ce que tu as demandé)
                                  En fait ce sont tes 3 champs, mais en 1ère position j'ai ajouté la ligne obtenu avec ls
                                  pour pouvoir l'afficher en fonction de tri
                                  @tmp_trie = sort {
                                          $a->[1] <=> $b->[1]
                                                  ||
                                          $a->[2] <=> $b->[2]
                                                  ||
                                          $a->[3] <=> $b->[3]
                                  } @tmp;
                                  Etape3
                                  Il nous reste à extraire du tableau trié seulement le 1er champ (la ligne obtenu avec ls)
                                  @trie = map { $_->[0] } @tmp_trie;


                                  0
                                  1. lami20j,

                                    Jusqu'a maintenant, tu as ecrit jusqu'a maintenant 5 scripts :

                                    Script 1 - Avec les separateurs et qui ne fonctionnait pas tout a fait.

                                    Script 2 - Celui que tu m'as envoye hier et avec les DATAS a l'interieur - IL FONCTIONNE TRES BIEN

                                    Script 3 - Celui que tu m'as envoye hier avec la ligne de commande - Il trie a l'inverse

                                    Script 4 - Celui que tu m'as envoye aujourdh'hui et avec les DATAS a l'interieur - IL FONCTIONNE TRES BIEN

                                    Script 5 - Celui que tu m'as envoye aujourdh'hui et avec la ligne de commande - Malheureusement, je viens de l'essayer et il trie ENCORE a l'inverse.

                                    C'est donc en ligne de commande que nous avons un probleme. Les scripts #2 et #4 FONCTIONNENT TRES BIEN.

                                    Merci de ton aide,
                                    0
                                    1. Modérateur
                                      Essaie celui ci en ligne de comamnde
                                      #!/usr/bin/perl
                                      
                                      while(<>){
                                        /.*:\d+\s+(.*)\[(\d+)x(\d+)\](\d{4})\..*/;
                                        chomp;
                                        push @nontrie,[$_,$2,$3,$4];
                                      }
                                      
                                      
                                      @trie = map {$_->[0]}
                                              sort {
                                                    $a->[1] <=> $b->[1]
                                                            ||
                                                    $a->[2] <=> $b->[2]
                                                            ||
                                                    $a->[3] <=> $b->[3]
                                              }
                                              map { $_ } @nontrie;
                                      
                                      print "$_\n" for reverse @trie;
                                      
                                      
                                      0
                                      1. Non, toujours le meme resultat. Mais ce n'est pas si grave.

                                        lami20j, je voulais savoir si on pouvait afficher le contenu de la variable $_ (l'ensemble des valeurs de la liste).
                                        J'ai fait print $_ mais ca n'affiche rien.

                                        Merci
                                        0
                                        • 1
                                        • 2