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 :

Optimisation du code pour un traitement sur des fichiers text


Sujet :

Langage Perl

  1. #1
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 260
    Points : 19 423
    Points
    19 423
    Billets dans le blog
    63
    Par défaut Optimisation du code pour un traitement sur des fichiers text
    Bonjour,

    Je suis spécialisé en VB, VBA..

    et je débute en perl, je n'est donc peut-être pas les bons trucs pour programmer au mieux en perl


    Je vous explique mon problème:

    j'ai 1 fichier1 du style:

    //
    ID 1254554545
    AC 9999999988
    UT 127595689
    DE 7979797979
    PA klgdkflmkdlfg
    NR gdg^p*df$^g$^df$g^d$
    //
    ID 777777777777
    AC 6666666666
    UT 127599999
    //

    etc..



    et un fichier2 contenant les termes "ID", "AC", "DE"

    ce que je veux faire c'est remplacer les "ID", "AC" et "DE" du fichier2 par ce qui suit ID, AC et DE dans le fichier1 et créer un fichier3 résultat des remplacement:

    Par exemple:

    "ID" remplacé par "1254554545"
    "AC" remplacé par "9999999988"
    "DE" remplacé par "7979797979"


    Pour le moment, j'ouvre le fichier2 d'1 bloc et lit son contenu dans une chaine $textfile2

    J'ouvre le fichier1 et le lis ligne par ligne, je teste à chaque fois (avec substr())si les 2 premiers caractères de $ligne sont égaux à "ID", "AC", "DE" si oui alors je substitue "ID" par le reste de la ligne (en utilisant sustr()) dans textfile2

    etc.. pour chaque ligne,

    et quand j'ai finit de lire le fichier1

    je créer le fichier3 avec la chaine textfile2...


    Ma question est: Y-a-t'il une facon plus simple de procéder en perl ,


    Merci par avance,

    Denis
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  2. #2
    Membre éprouvé Avatar de MarneusCalgarXP
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    911
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 911
    Points : 1 118
    Points
    1 118
    Par défaut
    Personnellement, en tant que programmeur fainéant, je chargerais le contenu de fichier1 dans une hash (clé <-> valeur) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    my $hash = ();
    while (my $line = <FILE1>)
    {
       next, unless ($line =~ /^(\S+)\s+(\S+)$/);
       my ($cle, $valeur) = ($1, $2);
       $hash{$cle} = $valeur;
    }
    (\S correspond à tout ce qui est différent d'un espace)
    (\s correspond à tout ce qui est un espace)


    Puis j'ouvrirais fichier 2 et je le lirais ligne par ligne:
    A chaque ligne, j'executerais des regexp de substitution globale, et j'écrirais le résultat dans file3 directement (donc ligne par ligne).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    while (my $line = <FILE2>) {
        foreach my $cle (keys %hash) {
            my $valeur = $hash{$cle};
            $line =~ s/$cle/$valeur/g;
        }
        print FILE3 $line;
    }
    Je n'ai pas mis le code d'ouverture et de fermeture des fichiers, mais ça, c'est trivial

    Je ne répond à aucune question technique par MP.

    Si votre problème est réglé, n'oubliez pas Dans tous les cas

  3. #3
    Membre expert
    Avatar de 2Eurocents
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    2 177
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 2 177
    Points : 3 166
    Points
    3 166
    Par défaut
    Citation Envoyé par User
    Ma question est: Y-a-t'il une facon plus simple de procéder en perl ?
    La réponse est certainement : oui !

    Maintenant, pour te dire comment ... l'énoncé manque encore un peu de précision :
    - Visiblement, dans fichier1, les ID, AC, UT, etc. peuvent être répétés, ce qui exclut l'usage de tables de hachage . Qu'en est-il dans le fichier 2 ? Y a t'il une correspondance du premier au premier, du second au second, etc. ?
    - Les volumes de données sont-ils importants ou non (possibilité de faire tout le traitement en mémoire) ?
    - Ton fichier2 contient il les éléments sur une seule ligne, ou ligne par ligne, ou n'importe comment ?
    - Ton fichier3, c'est une espèce de rapport des remplacements faits dans fichier2 ou bien c'est le résultat de ces remplacements ?
    La FAQ Perl est par ici
    : La fonction "Rechercher", on aurait dû la nommer "Retrouver" - essayez et vous verrez pourquoi !

  4. #4
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 260
    Points : 19 423
    Points
    19 423
    Billets dans le blog
    63
    Par défaut
    @2Eurocents

    Merci pour la rapidité:

    Je te répond à quelques questions, mais j'ai besoin de précisions à demander à une tierse personne pour être plus précis, je te répondrais ce soir:

    En fait mon fichier1 (pattern.txt) doit être découpé en morceaux avec le signe "//"

    dans fichier1 entre chaque (// voir plus bas) les ID, AC, UT, etc. ne se répètent pas il me semble (je me renseigne..)

    Le fichier1 (fichier pattern.txt: protéines..) peut-être assez grand a priori (je me renseigne..)

    Fichier2: le fichier2 contient les éléments n'importe comment:

    TR PROSITE AC ID ,I,lwo
    Names: DE
    FT FTDESC # # FTKEY


    et le fichier3 est le résultat des remplacements,

    en fait pour être plus précis, je créer 1 fichier résultat pour chaque morceau de fichier entre (//..//):

    // (1er morceau)
    ID 1254554545
    AC 9999999988
    UT 127595689
    DE 7979797979
    PA klgdkflmkdlfg
    NR gdg^p*df$^g$^df$g^d$
    // (2ème morceau)
    ID 777777777777
    AC 6666666666
    UT 127599999
    //


    @+

    et merci encore à tous les 2,

    A bientot

    Denis
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  5. #5
    Membre chevronné
    Avatar de Woufeil
    Profil pro
    Étudiant
    Inscrit en
    Février 2006
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2006
    Messages : 1 076
    Points : 2 004
    Points
    2 004
    Par défaut
    Bonsoir

    Hum, dans ce cas il suffit de créer un hash par morceau qui sera la table des correspondances ! Il n'y a pas de redondances pour un ID/AC/UT... dans le même morceau je suppose ?

    L'avantage de cette solution est qu'elle est valable même si le fichier 1 est gros.

    PS : tu pourrais effacer ton doublon stp ?
    "En essayant continuellement, on finit par réussir. Donc : plus ça rate, plus on a de chances que ça marche" (devise Shadock)
    Application :

    ainsi qu'à regarder la avant de poser une question.

    La rubrique Perl recrute, contactez-moi.

  6. #6
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 260
    Points : 19 423
    Points
    19 423
    Billets dans le blog
    63
    Par défaut
    Désolé,

    Je vous précise tout ca d'ici demain, ce soir pas moyen d'avoir plus d'info du responsable du projet...

    Bonne soirée,

    @+
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  7. #7
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 260
    Points : 19 423
    Points
    19 423
    Billets dans le blog
    63
    Par défaut
    Bonjour à tous,

    Je précise mon problème après avoir eu des infos supplémentaires:

    1) Le fichier1 fait environ 1.63 Mo
    Dans le fichier1 les entêtes de ligne ID, AC, DE sont uniques par bloc et positionner au même endroit (ID 1er ligne du bloc, AC 2ème ligne du bloc..)
    Les blocs sont délimité par le signe // dans le fichier1.

    et le fichier1 est du style:

    ID ASN_GLYCOSYLATION; PATTERN.
    AC PS00001;
    DT APR-1990 (CREATED); APR-1990 (DATA UPDATE); APR-1990 (INFO UPDATE).
    DE N-glycosylation site.
    PA N-{P}-[ST]-{P}.
    CC /TAXO-RANGE=??E?V;
    CC /SITE=1,carbohydrate;
    CC /SKIP-FLAG=TRUE;
    CC /VERSION=1;
    PR PRU00498;
    DO PDOC00001;
    //
    ID GLYCOSAMINOGLYCAN; RULE.
    AC PS00002;
    DT APR-1990 (CREATED); APR-1990 (DATA UPDATE); APR-1990 (INFO UPDATE).
    DE Glycosaminoglycan attachment site.
    PA S-G-x-G.
    RU Additional rules:
    RU There must be at least two acidic amino acids (Glu or Asp) from -2 to
    RU -4 relative to the serine.
    CC /TAXO-RANGE=??E??;
    CC /SITE=1,glycosaminoglycan;
    CC /SKIP-FLAG=TRUE;
    CC /VERSION=1;
    DO PDOC00002;
    //



    etc...


    2) Le fichier2 est le squelette du style:

    TR PROSITE; VARAC; VARID; 1; level=0
    XX
    Names: VARDE
    Function: none
    XX
    XX
    FT From: VARAC


    Je dois créer un fichier résultat par bloc

    et je dois remplacer dans le fichier2 (le squelette):
    VARID, VARAC, VARDE

    par la [chaine] qui suit ID, AC et DE dans le fichier1 et positionnée comme suit:


    pour VARID:
    ID___[chaine];


    (ou _ représente un espace
    [chaine] représente la chaine à extraire et à substituer à VARID dans fichier2
    et ; est le délimiteur de fin)


    pour VARAC:
    AC___[chaine]


    (la chaine fait 7 caractères)


    etc...

    Vous me parlez de table de hachage mais j'avoue être dans le flou (je débute et ne maitrise pas bien les synthaxes perl...)

    (Comment puis-je extraire une chaine à partir de délimiteur comment construire ma table de hachages..)

    Pourriez vous m'aider ou me donner un bout de code pour démarrer qui collerai à mon problème ?


    Merci beaucoup,


    Denis
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  8. #8
    Membre éprouvé Avatar de MarneusCalgarXP
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    911
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 911
    Points : 1 118
    Points
    1 118
    Par défaut
    Mon code est toujours d'actualité, à part qu'il faut juste y ajouter la gestion des n° de paragraphes !!

    1) remplissage de la hash par paragraphes
    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
    # hash qui va recueillir les données
    my $hash = ();
    # n° de paragraphe
    my $idparagraph = 0;
    # délimiteur fichier 1
    my $delimiter1 = '//';
    
    while (my $line = <FILE1>)
    {
       # on supprime le retour chariot à la fin de la ligne
       chomp($line);
       # si la ligne est '//', on incrémente le n° de paragraphe et on passe à l'analyse de la ligne suivante
       if ($line eq $delimiter1) { $idparagraph++ ; next; }
       # si la ligne n'est pas dans le bon format, on l'ignore. par la même occasion, on récupère les données si elle est au bon format !
       next, unless ($line =~ /^(\S+)\s+(\S+)$/);
       # on récupère et on stocke les données par paragraphe
       my ($cle, $valeur) = ($1, $2);
       $hash{idparagraph}{$cle} = $valeur;
    }
    Ensuite, quel est ton délimiteur de paragraphe dans fichier 2 ? C'est la chaine XX ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    my $delimiter2 = 'XX';
    $idparagraph = 0;
     
    while (my $line = <FILE2>) {
        chomp($line);
        if ($line eq $delimiter2) { $idparagraph++ ; next; }
        foreach my $cle (keys %{ $hash{$idparagraph} }) {
            my $valeur = $hash{$idparagraph}{$cle};
            $line =~ s/VAR$cle/$valeur/g;
        }
        print FILE3 $line . "\n";
    }

    Je ne répond à aucune question technique par MP.

    Si votre problème est réglé, n'oubliez pas Dans tous les cas

  9. #9
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 260
    Points : 19 423
    Points
    19 423
    Billets dans le blog
    63
    Par défaut
    merci MarneusCalgarXP,

    Je vais étudier ton code

    Dans le fichier2 il n'y a pas de délimiteur de paragraphe, c'est un petit fichier squelette que sert a créer des fichiers resultats à partir des infos recherché dans les blocs du fichier1:


    bloc1:
    -parcours du bloc1 du fichier1 , repérage des chaines (sur ligne ID, ligne AC..)
    -Puis Copie du fichier2 dans une variable ($textfile2),
    -remplacement des varID,VarAC dans $textfile2 squelette
    -création du fichier "résultat1" à partir de la chaine $textfile2

    bloc2:
    -parcours du bloc2 du fichier1 , repérage des chaines (sur ligne ID, ligne AC..)
    -Puis Copie du fichier2 dans une variable ($textfile2),
    -remplacement des varID,VarAC dans $textfile2 squelette
    -création du fichier "résultat2" à partir de la chaine $textfile2



    etc

    Voila, merci encore,

    J'étudie les expression régulière et autres pas évident ..

    @+
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

Discussions similaires

  1. Optimiser temps de traitement sur des requêtes simples
    Par yoyo88 dans le forum Langage SQL
    Réponses: 21
    Dernier message: 20/02/2015, 12h35
  2. Traitement sur des fichiers/répertoires windows
    Par Invité dans le forum Général Python
    Réponses: 2
    Dernier message: 23/02/2012, 09h04
  3. optimisation du code pour des combobox
    Par oscar.cesar dans le forum Macros et VBA Excel
    Réponses: 12
    Dernier message: 08/03/2008, 13h30
  4. traitement sur des secondes
    Par richou dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 20/03/2006, 11h00
  5. [javac] code pour lancer la compilation des classes
    Par viena dans le forum Général Java
    Réponses: 6
    Dernier message: 19/07/2004, 17h41

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