IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Concaténer n lignes de n fichier


Sujet :

Langage Perl

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 11
    Points : 10
    Points
    10
    Par défaut Concaténer n lignes de n fichier
    Bonjour,

    Je suis à la recherche de pistes pour résoudre un petit problème. L'opération que je veux réaliser porte peut être un nom qu m'aurait permis de faire plus de recherches google, mais je sèche là

    J'ai N fichiers, contenant chacun une liste ce longueur non fixe.
    Quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    @un = qw/TO TA/;
    @de = qw/1 2 3/;
    @tr = qw/a/;
    @qu = qw/I II/;
    Je dois en faire un fichier qui contiendrait :
    TO 1 a I
    TO 1 a II
    TO 2 a I
    TO 2 a II
    TO 3 a I
    TO 3 a II
    TA 1 a I
    and so on...

    Je suis preneur de toutes pistes... j'ai trituré ce problème toute la journée et je sèche lamentablement

    Merci d'avance pour toute aide.

  2. #2
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 499 184
    Points
    499 184
    Par défaut
    Bonjour,

    Voici en imbriquant tes tableaux.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    my @un = qw/TO TA/;
    my @de = qw/1 2 3/;
    my @tr = qw/a/;
    my @qu = qw/I II/;
     
    foreach my $a ( @un ) {
    	foreach my $b ( @de ) {
    		foreach my $c ( @tr ) {
    			foreach my $d ( @qu ) {
    				print "$a\t$b\t$c\t$d\n";
    			}
    		}
    	}
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    TO      1       a       I
    TO      1       a       II
    TO      2       a       I
    TO      2       a       II
    TO      3       a       I
    TO      3       a       II
    TA      1       a       I
    TA      1       a       II
    TA      2       a       I
    TA      2       a       II
    TA      3       a       I
    TA      3       a       II

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 11
    Points : 10
    Points
    10
    Par défaut
    Merci Djibril pour cette réponse.

    Ce qui est compliqué à gérer, dans mon cas, c'est le nombre non fixe de fichiers en entrée.

  4. #4
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Dans ce cas, il faut sans doute envisager une petite procédure appelée récursivement pour chaque niveau d'imbrication.

    Cela dit, il existe probablement un module CPAN. Je ne peux pas trop regarder maintenant depuis ma mini-tablette, mais recherche "CPAN cartesian product" ou "CPAN math cartesian product" ou "CPAN combinatorics" ou "CPAN math combinatorics" ou "CPAN algorithm combinatorics". Tu devrais récupérer une série de modules dont un ou plusieurs feront ce que tu veux faire.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 11
    Points : 10
    Points
    10
    Par défaut
    Bonjour,

    Merci lolo78. Effectivement, il me manque les mots clefs pour faire une recherche google et/ou cpan.
    Je vais creuser par là

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 11
    Points : 10
    Points
    10
    Par défaut
    Peut être de ce coté ci :

  7. #7
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 499 184
    Points
    499 184
    Par défaut
    Voilà !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/usr/bin/perl 
    use strict;
    use warnings;
    use Set::Product qw(product);
     
    my @un = qw/TO TA/;
    my @de = qw/1 2 3/;
    my @tr = qw/a/;
    my @qu = qw/I II/;
    my @mes_tableaux = (\@un, \@de, \@tr, \@qu);
     
    product { print "@_\n" } @mes_tableaux;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    TO 1 a I
    TO 1 a II
    TO 2 a I
    TO 2 a II
    TO 3 a I
    TO 3 a II
    TA 1 a I
    TA 1 a II
    TA 2 a I
    TA 2 a II
    TA 3 a I
    TA 3 a II

  8. #8
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Bonsoir,
    le mieux est sans aucun doute d'utiliser l'un des modules du CPAN, comme l'a fait Djibril ci-dessus.

    Toutefois, il peut être intéressant de coder l'algorithme soi-même à des fins pédagogiques, ou pour s'entraîner. Ou, dans mon cas ici, juste pour le fun:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #!/usr/bin/perl 
    use strict;
    use warnings;
    use feature "say";
     
    my @un = qw/TO TA/;
    my @de = qw/1 2 3/;
    my @tr = qw/a/;
    my @qu = qw/I II/;
    my @mes_tableaux = (\@un, \@de, \@tr, \@qu);
    combine("", @mes_tableaux);
     
    sub combine {
        my ($str, @tableaux) = @_;
        my $tabref = shift @tableaux;
        if (@tableaux) {
            combine ("$str $_", @tableaux) for @$tabref;
        } else {
            say "$str $_" for @$tabref;
        }
    }
    La fonction combine lit chaque élément du premier tableau qui lui est passé et s'appelle récursivement avec la liste des tableaux restants, et ainsi de suite. La descente récursive s'arrête quand le tableau de tableaux est vide.

    Voici le résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     TO 1 a I
     TO 1 a II
     TO 2 a I
     TO 2 a II
     TO 3 a I
     TO 3 a II
     TA 1 a I
     TA 1 a II
     TA 2 a I
     TA 2 a II
     TA 3 a I
     TA 3 a II
    J'ai mis moins de temps à écrire le code et à le tester (5 ou 6 minutes) qu'à rédiger ce message (8 ou 9 minutes).

  9. #9
    Responsable Perl et Outils

    Avatar de djibril
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    19 820
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 19 820
    Points : 499 184
    Points
    499 184
    Par défaut

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 11
    Points : 10
    Points
    10
    Par défaut
    Merci pour vos retours.

    J'ai combiné le module que j'avais indiqué (merci pour les mots clefs qui m'ont permis d'orienter mes recherches) et une boucle sur le contenu de mon @ARGV pour combiner la liste des N tableaux entre eux.

  11. #11
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Tant mieux si tu as résolu ton problème, et l'utilisation d'un de ces modules est bien la solution que je recommandais.

    Jette tout de même un coup d’œil au code "manuel" que je t'ai proposé, peut-être que tu apprendras quelque chose (enfin, j'espère). Et n'hésite pas à demander si tu te poses des questions.

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 11
    Points : 10
    Points
    10
    Par défaut
    Je peux vous mettre mon programme, même si il va faire bondir les puristes, si vous le souhaitez.

  13. #13
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Oui, vas-y, montre ton programme.

  14. #14
    Membre confirmé
    Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Points : 641
    Points
    641
    Par défaut on peut utiliser glob
    pour les curieux, on peut utiliser la fonction glob et résoudre le problème en un uniligne

    Par exemple à partir d'un tableau de tableaux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $ perl -E '@aoa = ([qw(TO TA)], [qw(1 2 3)], [qw(a)], [qw(I II)]); $s = "%"; say s/$s/ /gr for glob join $s, map { "{" . join(",", @$_) . "}" } @aoa'
    TO 1 a I
    TO 1 a II
    TO 2 a I
    TO 2 a II
    TO 3 a I
    TO 3 a II
    TA 1 a I
    TA 1 a II
    TA 2 a I
    TA 2 a II
    TA 3 a I
    TA 3 a II
    $
    L'adaptation à un nombre quelconque (limites de glob à vérifier?) de fichiers est facile. On commence par générer les fichiers de test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ perl -E '@aoa = ([qw(TO TA)], [qw(1 2 3)], [qw(a)], [qw(I II)]); for (@aoa) { open $f, ">", sprintf("tst%03d", ++$cnt); say {$f} "@$_" }'
    $
    petite vérif :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ for i in tst*; do echo $i : `cat $i`; done
    tst001 : TO TA
    tst002 : 1 2 3
    tst003 : a
    tst004 : I II
    $
    Il n'y a plus qu'à initialiser notre tableau de tableaux à partir du contenu des fichiers passés en paramètre de la ligne de commande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $ perl -E '@aoa = map { local (@ARGV, $/) = $_; [split /\s+/, <> ]} @ARGV; $s = "%"; say s/$s/ /gr for glob join $s, map { "{" . join(",", @$_) . "}" } @aoa' tst*
    TO 1 a I
    TO 1 a II
    TO 2 a I
    TO 2 a II
    TO 3 a I
    TO 3 a II
    TA 1 a I
    TA 1 a II
    TA 2 a I
    TA 2 a II
    TA 3 a I
    TA 3 a II
    $
    autre exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $ echo pomme poire cassis > fruits
    $ echo rouge jaune violet > couleurs
    $ perl -E '@aoa = map { local (@ARGV, $/) = $_; [split /\s+/, <> ]} @ARGV; $s = "%"; say s/$s/ /gr for glob join $s, map { "{" . join(",", @$_) . "}" } @aoa' fruits couleurs
    pomme rouge
    pomme jaune
    pomme violet
    poire rouge
    poire jaune
    poire violet
    cassis rouge
    cassis jaune
    cassis violet
    $
    Sauf indication contraire tous les codes que je présente sont utilisables et testés (mais sans garantie d'aucune sorte)
    J'apporte beaucoup de soin à la rédaction de mes posts et apprécie les retours donc merci de s'il vous paraissent pertinents ou utiles
    Lazyness, Impatience and Hubris are good for you

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [sh] Exercice concaténation des lignes impaires d'un fichier
    Par ettar dans le forum Shell et commandes GNU
    Réponses: 6
    Dernier message: 29/05/2014, 13h02
  2. Concaténation d'un champ supplémentaire pour chaque ligne d'un fichier
    Par saladin443 dans le forum Shell et commandes GNU
    Réponses: 3
    Dernier message: 27/05/2013, 12h49
  3. Réponses: 22
    Dernier message: 28/10/2010, 17h26
  4. Réponses: 2
    Dernier message: 28/07/2009, 17h32
  5. Concaténation des lignes d'un fichier texte
    Par oranoutan dans le forum C
    Réponses: 9
    Dernier message: 14/07/2008, 19h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo