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 :

Comment ajouter des valeurs dans un fichier CSV avec PERL?


Sujet :

Langage Perl

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mai 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mai 2018
    Messages : 6
    Points : 2
    Points
    2
    Par défaut Comment ajouter des valeurs dans un fichier CSV avec PERL?
    Bonjour à toutes et à tous,

    Dans le cadre d'un cours de Statistiques, je dois matcher des mots dans un tableur en CSV et afficher dans une colonne le nombre de mot par ligne afin de pouvoir les exploiter.
    par exemple, si je dois matcher le mot "je":

    "je dois manger une pomme", 1
    "j'ai mangé une pomme et je suis content", 2
    "coucou", 0

    J'ai donc dévellopé le script suivant:
    Nom : scriptOK.png
Affichages : 995
Taille : 56,1 Ko

    J'arrive bien à matcher les mots qui m'intéressent mais pas à inscrire le résultat dans le fichier. C'est la ligne 19 qui me pose problème.
    J'ai bien cherché une solution un peu partout mais je n'ai rien trouvé de concluant.
    J'espère avoir été précis dans l'explication de mon problème.

    Je vous remercie d'avance pour votre aide.

    Bien cordialement,

    Gandalf

  2. #2
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    décembre 2012
    Messages
    3 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : décembre 2012
    Messages : 3 909
    Points : 11 486
    Points
    11 486
    Par défaut
    Bonjour,

    Tu dois travailler avec 2 fichiers, l'un en lecture pour lire tes données à traiter et un autre en écriture pour y mettre le résultat que tu veux.

    Le $csv->getline, c'est pour lire et le $csv->print pour écrire.

    PS: Utilise les balise code (le bouton avec le '#' ) pour mettre ton code au lieu d'une copie d'écran.
    Cordialement.

  3. #3
    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 465
    Points
    12 465
    Billets dans le blog
    1
    Par défaut
    J'ajoute que, même à supposer qu'il suffise de modifier le record pour modifier le fichier (ce qui n'est pas le cas), la logique du code est fausse.

    Les deux lignes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $record->[6] = $count;
    $count = 0;
    devraient se trouver après l'accolade fermante qui les suit actuellement (après l'accolade qui ferme le foreach).

    Mais, bon, dans l'immédiat, la priorité est déjà d'écrire dans un fichier différent de celui que tu lis.

  4. #4
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mai 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mai 2018
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Bonsoir à vous deux,

    Merci pour votre aide, j'y vois déjà plus clair.
    J'ai modifié le script ainsi:

    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
    22
    23
    24
    25
    26
    27
    use strict;
    use warnings;
    use Text::CSV;
    use Text::CSV_XS;
     
     my $csv = Text::CSV->new({ binary => 1 }) or die "Error creating CSV object: ".Text::CSV->error_diag ();
     
     open my $fh, "<:encoding(utf8)", "CorpusSMS.csv" or die "Error reading CSV file: $!";
     my $linea = <$fh>;
     my $count = 0;
     my @tab;
     while ( my $record = $csv->getline( $fh ) ) {
     	my @tab = split (/ /, $record->[5]);
     	foreach my $elem (@tab){
     		if ($elem =~ /^je$/){
     			$count++;
     		}
     	}
     	my $csv2 = Text::CSV->new ( { binary => 1 } ) or die "Cannot use CSV: ".Text::CSV->error_diag ();                      
    	open my $fh2, ">>:encoding(utf8)", "Test.csv" or die "Test.csv: $!";         
    	$csv2->print($fh2, [$count.',']);                                       
    	close $fh2;   
    	$count= 0;
     }
     
     $csv->eof or $csv->error_diag();
     close $fh;
    J'arrive bien à lire dans le premier fichier et à écrire dans le second, ça avance donc!
    Il y a cependant encore un détail que je n'ai pas compris, comment fait-on pour ne pas écrire les valeurs dans une même cellule mais bien en une colonne?
    J'ai été voir la doc mais je pense être passé à côté de la subtilité.

    D'avance merci et bonne soirée!

    Gandalf

  5. #5
    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 465
    Points
    12 465
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    je ne suis pas sûr de bien comprendre ta question, mais si veux juste aller à la ligne, il suffit sans doute d'ajouter un caractère nouvelle ligne (\n) à la ligne en sortie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $csv2->print($fh2, [$count . ",\n"]);      # NB: il faut des guillemets doubles pour que la chaîne "\n" soit interpolée en nouvelle ligne
    J'ajoute que tu ouvres et fermes ton fichier de sortie pour chaque ligne en entrée, ce qui marche certainement mais est très inefficace. Il est bien préférable d'ouvrir le fichier de sortie une seule fois avant d'entrer dans la boucle while et de le fermer une fous pour toutes après être sorti de ladite boucle.

    Enfin, si c'est juste pour écrire un compteur par ligne (si j'ai bien compris), il n'est pas nécessaire d'utiliser le module Text::CSV ou Text::CSV_XS pour le fichier de sortie qui n'est apparemment qu'un simple fichier texte et non un CSV.

  6. #6
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mai 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mai 2018
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    Je pense en effet n'avoir pas été très clair, je vais préciser mon problème ici.
    En somme, une fois que j'ouvre le fichier de sortie dans un tableur pour vérifier si je peux l'utiliser à des fins statistiques, je tombe sur ceci:
    Nom : sortie_csv.png
Affichages : 388
Taille : 21,3 Ko

    Toutes les valeurs du compteur sont donc comprises dans une seule cellule, ce qui est problématique.
    Je souhaiterais en effet pouvoir utiliser la dite colonne de cette façon (DEIC):
    Nom : DEIC_attendu.png
Affichages : 397
Taille : 10,6 Ko

    Et lorsque j'ajoute un \n quand j'écris mon compteur, j'ai le même problème mais dans l'autre sens, c'est-à-dire qu'au lieu de s'enchainer horizontalement, les valeurs se suivent de façon verticale et toujours dans une même cellule. Le problème est donc de pouvoir décider pour chaque valeur du compteur, à chaque fin de boucle, que la valeur doit être isolée dans la cellule en-dessous de la cellule précédente. Et ainsi pour tout le fichier. Cela me permettrait donc d'avoir les valeurs du compteur dans une colonne et de pouvoir mettre en relation cette variable avec d'autres.

    J'espère avoir été plus clair.

    Encore merci pour vos éclaircissements, j'ai corrigé la fermeture de fichier problématique.

    Cordialement,

    Gandalf.

  7. #7
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    décembre 2012
    Messages
    3 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : décembre 2012
    Messages : 3 909
    Points : 11 486
    Points
    11 486
    Par défaut
    En gros, ce que tu veux, c'est quelque chose comme ça (ici, c'est juste un exemple rapide, bien sur) ?
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ cat /tmp/text1.txt 
    je suis là
    je mange, je bois
    coucou
    $ perl -ne 'chomp;printf "\"%s\",%i\n" , $_ , (s/je/je/g)' /tmp/text1.txt 
    "je suis là",1
    "je mange, je bois",2
    "coucou",0
    Cordialement.

  8. #8
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mai 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mai 2018
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    En somme oui mais appliqué à un corpus en fichier CSV.
    Lire en entrée une colonne de textes, compter pour chaque cellule les occurences d'un mot et stocker le nombre d'occurences dans une autre colonne.
    Ainsi un logiciel de stats (SPSS) pourra faire le lien entre les deux variables.
    Mon problème réside principalement à mettre en forme le résultat du compteur pour que cela concorde avec la colonne de textes.
    C'est pour cela que je veux écrire en csv, pour le filer à SPSS pour ensuite faire mes analyses.

    Cordialement,

    Gandalf.

  9. #9
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mai 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mai 2018
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Après avoir bidouillé, j'arrive enfin à un résultat presque parfait!

    Nom : okcsv.png
Affichages : 374
Taille : 13,1 Ko

    J'ai une dernière question: d'où viennent les guillements dans le tableur? Ils risquent en effet de poser problème dans mes analyses statistiques.
    Voici mon code:

    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
    22
    23
    24
    25
    26
    27
    28
    29
     
    use strict;
    use warnings;
    use Text::CSV;
    use Text::CSV_XS;
     
     my $csv = Text::CSV->new({ binary => 1 }) or die "Error creating CSV object: ".Text::CSV->error_diag ();
     
     open my $fh, "<:encoding(utf8)", "CorpusSMS.csv" or die "Error reading CSV file: $!";
     my $csv2 = Text::CSV->new ( { binary => 1 } ) or die "Cannot use CSV: ".Text::CSV->error_diag ();                      
     open my $fh2, ">>:encoding(utf8)", "Test.csv" or die "Test.csv: $!";         
     my $linea = <$fh>;
     my $count = 0;
     my @tab;
     my $ponc = ", \n";
     while ( my $record = $csv->getline( $fh ) ) {
     	my @tab = split (/ /, $record->[5]);
     	foreach my $elem (@tab){
     		if ($elem =~ /^je$/){
     			$count++;
     		}
     	}
    	$csv2->print($fh2, [$count.$ponc]);                                        
    	$count= 0;
     }
     
     $csv->eof or $csv->error_diag();
     close $fh;
     close $fh2;
    Un grand merci pour votre aide et vos conseils, ça m'a permis d'y voir plus clair.

    Cordialement,

    Gandalf

  10. #10
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mai 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : mai 2018
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Bonsoir,

    J'ai finalement réussi à enregistrer mes données sans ces " " en sauvegardant les données dans un fichier texte simple. Il semblerait en effet que les modules CSV lisent très bien mais écrivent moins facilement.

    Problème résolu!

    Bonne soirée,

    Gandalf

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 26/03/2014, 16h30
  2. [WM18] Comment enregistrer des valeurs dans un fichier texte sous IOS
    Par nico78 dans le forum Windev Mobile
    Réponses: 1
    Dernier message: 26/08/2013, 16h13
  3. Réponses: 13
    Dernier message: 09/11/2011, 13h06
  4. Comment sauvegarder des valeurs dans un fichier txt
    Par NELLLY dans le forum MATLAB
    Réponses: 3
    Dernier message: 16/04/2007, 18h39
  5. Réponses: 1
    Dernier message: 16/01/2007, 16h39

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