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 :

Découper un fichier selon un code ascii


Sujet :

Langage Perl

  1. #1
    Futur Membre du Club
    Inscrit en
    Mars 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 16
    Points : 7
    Points
    7
    Par défaut Découper un fichier selon un code ascii
    Bonjour,

    J'ai un gros fichier qui vient de l'exportation de courriel de Lotus Notes. Celui-ci me permet de mettre un code ascii en fin de chaque message, par défaut le code 12. J'aimerai maintenant découper de fichier à la suite de ce code et le mettre dans un nouveau fichier. Voici ce que j'ai fait :

    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
     
    my $chr = chr(12);
     
    my $prefix = 'slice';
    $count = 0;
     
    open (FILE, $ARGV[0]);
    while (<FILE>) {
            if (/$chr/) {
                    $count++;
                    open (OUTPUT,">$prefix.$count");
                    print OUTPUT $`;
                    close OUTPUT;
            }
    }
    J'obtiens bien mes fichiers slice mais ils sont vides. Pourtant je ne copie que ce qui vient avant le $chr..

    Votre aide serait la bienvenue.

    Merci

  2. #2
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 58

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    open my $fh, '<', $filename;
    {
        local $/ = chr(12);    
        while (my $block = <$fh>) {
            # ...
        }
    }
    Modifie localement le séparateur d'enregistrement ($/). Par défaut $/ vaut \n.

  3. #3
    Futur Membre du Club
    Inscrit en
    Mars 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Salut et merci pour ta réponse.

    Mais je ne l'a comprends pas bien. Quelles sont les modifications à apporter à mon code ?

    Encore merci !

  4. #4
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 58

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    L'exemple lit par bloc séparé par des Form Feed (Char 12 en ASCII) au lieu de lire ligne à ligne (c'est à dire par blocs séparés par des Line Feed).

    J'ai l'impression que tu veux quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $count = 0;
    open my $infh, '<', shift
        or die "$!\n";
    {
        local $/ = chr(12);    
        while (my $block = <$infh>) {
            chomp; # si tu veux te débarasser du séparateur
            $count += 1;
            open my $outfh, '>', 'slice'.$count
                or die "$!\n";
            print $outfh, $block;
            close $outfh; 
        }
    }

  5. #5
    Futur Membre du Club
    Inscrit en
    Mars 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Bonjour,

    J'ai essayé le code proposé, mais il ne marche pas, aucun fichier slice.* n'est créé. Voici le code exact :

    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
     
    #!/usr/bin/perl
    #
    $count = 0;
    my $infh = 'aqaq.txt';
    open $infh, '<', shift or die("$!\n");
    {
                      local $/ = chr(12);
                      while (my $block = <$infh>) {
                                             chomp;
                                             $count += 1;
                                             open my $outfh, '>', 'slice'.$count or die "$!\n";
                                             print $outfh, $block;
                                             close $outfh;
                      }
    }
    Question : comment puis-je vérifier qu'il y a bien un caractère 12 dans le fichier 'aqaq.txt' ?

    Réponse : avec vim sous Linux, se mettre sur le caractère et taper :ascii

    Dans mon cas, ça me donne bien le 12.

    Question 2 : à quoi sert le shift dans le code puisque plus tard dans le while on lit block par block ?

    Merci pour le coup de main, car là je n'y pige plus rien.

  6. #6
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 58

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    1. Le shift remplaçait ton $ARGV[0]

    2. Dans open, $infh contient le file handle pas le nom du fichier, tu devrais avoir plutôt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my $filename = 'aqaq.txt';
    open my $infh, '<', $filename 
        or die("$!\n");
    3. Si tu veux savoir, si ton fichier contient des chr(12), tu peux essayer l'uniligne suivant en ligne de commande (imprime le numéro des lignes qui contiennent un Form Feed)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    perl -lne 'print $. if /\f/' aqaq.txt

  7. #7
    Futur Membre du Club
    Inscrit en
    Mars 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par iblis Voir le message
    1. Le shift remplaçait ton $ARGV[0]
    Ah ok, merci.

    2. Dans open, $infh contient le file handle pas le nom du fichier, tu devrais avoir plutôt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my $filename = 'aqaq.txt';
    open my $infh, '<', $filename 
        or die("$!\n");
    Effectivement. Mais ça ne marche toujours pas. Maintenant le résultat ressemble à un cat aqaq.txt (vais d'ailleurs changer ce nom de fichier..) et les 5 fichiers slice.*sont toujours vides...

    3. Si tu veux savoir, si ton fichier contient des chr(12), tu peux essayer l'uniligne suivant en ligne de commande (imprime le numéro des lignes qui contiennent un Form Feed)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    perl -lne 'print $. if /\f/' aqaq.txt
    ça marche nikel, la sortie me donne les bonnes lignes et il y en a 4 comme prévu. Je me demande maintenant si je ne vais pas écrire un script qui récupère ces numéro de lignes et qui me split le fichier en en tenant compte... ce sera peut-être plus simple que la direction que j'ai prise. Qu'en penses-tu ?

    En tout cas, merci mille fois pour ton aide.

  8. #8
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 58

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Oups en relisant, je vois une faute de frappe, désolé. (il ne faut pas virgule au print)

    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
    #!/usr/bin/perl -w
    use strict;
     
    $count = 0;
    open my $infh, '<', 'aqaq.txt'
        or die "$!\n";
    {
        local $/ = chr(12);    
        while (my $block = <$infh>) {
            chomp $block; 
            $count += 1;
            open my $outfh, '>', 'slice'.$count
                or die "$!\n";
            print $outfh $block;
            close $outfh; 
        }
    }
    (pour tester tu peux aussi faire des print sur la sortie standard)

  9. #9
    Futur Membre du Club
    Inscrit en
    Mars 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Citation Envoyé par iblis Voir le message
    Oups en relisant, je vois une faute de frappe, désolé. (il ne faut pas virgule au print)

    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
    #!/usr/bin/perl -w
    use strict;
     
    $count = 0;
    open my $infh, '<', 'aqaq.txt'
        or die "$!\n";
    {
        local $/ = chr(12);    
        while (my $block = <$infh>) {
            chomp $block; 
            $count += 1;
            open my $outfh, '>', 'slice'.$count
                or die "$!\n";
            print $outfh $block;
            close $outfh; 
        }
    }
    (pour tester tu peux aussi faire des print sur la sortie standard)
    Et bin dites donc, il fallait la voir celle-là ! maintenant ça marche comme désiré, merci !

    Je vais enfin pouvoir passer à la suite, qui est d'extraire de chacun de ces messages l'information qui m'est nécessaire. (Et donc probablement encore des questions, mais j'ouvrirai un nouveau post pour cela).

    Encore merci pour ton aide Iblis !


    PS : je me suis réjoui trop vite. En effet, le dernier fichier obtenu est presque vide, il ne contient qu'une ligne vide. C'est pas hyper important, mais comment pourrait-on faire pour ne pas l'avoir ?

    PS2 : en regardant de plus près mes fichiers slice$i, je m'aperçois que pour $i>1, le fichier commence par une ligne blanche. Et comme je comptais utiliser le fait que les données importantes commençaient *après* une ligne blanche (mais bien plus bas), ça risque de me poser des problèmes. Comment faire pour les virer ?

  10. #10
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 58

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Tu peux toujours ignorer des lignes vides (ici des blocs en fait) dans ta boucle de lecture
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    chomp $block;
    next if $block =~ /^$/;

  11. #11
    Futur Membre du Club
    Inscrit en
    Mars 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 16
    Points : 7
    Points
    7
    Par défaut
    Salut,

    J'ai bien rajouter le code proposé mais cela ne change absolument rien, les fichiers slice* ont exactement la même taille et il y a toujours une ligne blanche au début des fichiers slice$i pour $i>2. Le bloc maintenant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    {
                      local $/ = chr(12);
                      while (my $block = <$infh>) {
                                             chomp;
                                             next if $block =~ /^$/;
                                             $count += 1;
                                             open my $outfh, '>', "slice$count.txt" or die "$!\n";
                                             print $outfh $block;
                                             close $outfh;
                      }
    }

    Bon ce n'est pas très grave, je vais passer maintenant à la suite.

    Encore merci pour ton temps et ta patience Iblis.

Discussions similaires

  1. [WD17] Imprimer fichier client selon son code
    Par fidraman dans le forum WinDev
    Réponses: 2
    Dernier message: 05/08/2013, 16h09
  2. Fichier contenant tous les codes ASCII
    Par jfdruine dans le forum Unix
    Réponses: 5
    Dernier message: 08/07/2010, 13h33
  3. Découper un fichier selon des lignes données
    Par boobz dans le forum Langage
    Réponses: 4
    Dernier message: 28/03/2008, 08h17
  4. Code ASCII du symbole Euro
    Par FW-S dans le forum Delphi
    Réponses: 9
    Dernier message: 03/04/2007, 01h27

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