Menu

Enlever certaines lignes d'un fichier [Résolu]

Messages postés
261
Date d'inscription
dimanche 6 novembre 2005
Statut
Membre
Dernière intervention
23 mai 2019
- - Dernière réponse : artagon7
Messages postés
261
Date d'inscription
dimanche 6 novembre 2005
Statut
Membre
Dernière intervention
23 mai 2019
- 23 mai 2019 à 17:03
Bonjour,

Je veux extraire, d'une liste de mots présents dans un fichier (entree.txt), ceux qui se terminent par une certaine chaîne de caractères que j'aurai choisie préalablement. Le programme va enlever les mots du fichier initial entree.txt qui remplissent le critère et les insérer dans un autre fichier (sortie.txt).

Par exemple, si j'ai le fichier entree.txt suivant :

automne
bateau
brise
chameau
cheval
gâteau


et que ma chaîne est "eau" et que j'exécute mon programme, mon fichier sortie.txt doit contenir les mots suivants :

bateau
chameau
gâteau


et mon fichier initial entree.txt devient :

automne
brise
cheval


Le programme suivant :

#!/usr/bin/perl

open(INFILE, "entree.txt") or die "Le fichier ne s'ouvre pas: $!";
open(OUTFILE, ">sortie.txt") or die "Le fichier ne s'ouvre pas: $!";

while(<INFILE>)
{
  if (/eau\n/) {print OUTFILE "$_"};
}

close INFILE;
close OUTFILE;


génère le fichier de sortie désiré. Cependant, ce programme n'enlève pas les mots dans le fichier entree.txt.

Je voudrais savoir quelles lignes de commandes je dois ajouter pour obtenir le fichier d'entrée modifié.

Merci
Afficher la suite 

Votre réponse

3 réponses

Meilleure réponse
Messages postés
25304
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
23 mai 2019
5197
1
Merci
Bonjour,

ce programme n'enlève pas les mots dans le fichier entree.txt : oui normal, le programme lit le fichier entree.txt et réécrit les termes non supprimés dans le fichier sortie.txt.

Tu n'as qu'à créer un nouveau fichier sortie2.txt qui reprend les termes non repris dans sortie.txt

Dire « Merci » 1

Heureux de vous avoir aidé ! Vous nous appréciez ? Donnez votre avis sur nous ! Evaluez CommentCaMarche

CCM 39315 internautes nous ont dit merci ce mois-ci

artagon7
Messages postés
261
Date d'inscription
dimanche 6 novembre 2005
Statut
Membre
Dernière intervention
23 mai 2019
5 -
Salut,

Est-ce que cela fonctionnerait?

#!/usr/bin/perl

open(INFILE, "entree.txt") or die "Le fichier ne s'ouvre pas: $!";
open(OUTFILE, ">sortie.txt") or die "Le fichier ne s'ouvre pas: $!";
open(OUTFILE2, ">sortie2.txt") or die "Le fichier ne s'ouvre pas: $!";


while(<INFILE>)
{
  if (/eau\n/) {print OUTFILE "$_"}
  else {print OUTFILE2 "$_"};
}

close INFILE;
close OUTFILE;
close OUTFILE2;


Je ne sais pas si je peux changer le nom de OUTFILE. Est-ce un mot réservé du langage ou simplement le nom d'un pointeur?

Je ne peux l'essayer tout de suite car je n'ai pas mon ordinateur avec moi.

Merci
jee pee
Messages postés
25304
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
23 mai 2019
5197 > artagon7
Messages postés
261
Date d'inscription
dimanche 6 novembre 2005
Statut
Membre
Dernière intervention
23 mai 2019
-
Oui c'est d'un code comme celui là dont je parlais.

Je ne programme pas en perl, mais suivant cette page : https://www.tutorialspoint.com/perl/perl_files.htm OUTFILE n'est pas un nom du langage, tu pourrais utiliser une autre valeur.
artagon7
Messages postés
261
Date d'inscription
dimanche 6 novembre 2005
Statut
Membre
Dernière intervention
23 mai 2019
5 -
En principe, ça devrait marcher. Je vais revenir plus tard pour commenter le résultat. Merci beaucoup.
Commenter la réponse de jee pee
Messages postés
5106
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
22 mai 2019
771
1
Merci
Salut artagon7,

Le code tel que tu l'as corrigé devrait "fonctionner", cependant voilà quelques remarques.

Une regexp qui matche à partir de la fin de ligne devrait utiliser le point d'ancrage $, donc quelque chose comme
if (/eau$/)
au lieu de
if (/eau\n/)
, à moins que tu veuilles tester quelque chose de particulier.

Sur les fichiers, la syntaxe que tu utilises, qui utilise des descripteurs qui sont des identifiants globaux était celle préconisée par le langage Perl avant la sortie de Perl 5.6 en 2000, avec la syntaxe à 2 paramètres de open.

Pour l'ouverture et l'écriture de fichiers en Perl moderne, tu devrais lire cet article, qui est bien fait : https://perlmaven.com/open-files-in-the-old-way ces pratiques, toujours supportées par Perl, pouvant poser différents types de problèmes expliqués par l'auteur.

Malheureusement, il y a beaucoup de code qui traîne des copier-coller de pratiques obsolètes, et même de tutoriels en ligne (y compris celui sur tutorialspoint.com), ou de cours, qui enseignent du code de ce type.

https://perldoc.perl.org/functions/open.html est la documentation officielle

Tu devrais prendre l'habitude de faire tes programmes Perl avec les directives
use strict;
et
use warnings;
:

#!/usr/bin/perl

use strict;
use warnings;  

et terminer toutes tes lignes avec un point-virgule, même celles précédant immédiatement une accolade, afin d'éviter, qu'en ajoutant du code au contenu de l'accolade, tu te retrouves avec une erreur de syntaxe sur une ligne qui avant fonctionnait parfaitement.

Dal

Dire « Merci » 1

Heureux de vous avoir aidé ! Vous nous appréciez ? Donnez votre avis sur nous ! Evaluez CommentCaMarche

CCM 39315 internautes nous ont dit merci ce mois-ci

artagon7
Messages postés
261
Date d'inscription
dimanche 6 novembre 2005
Statut
Membre
Dernière intervention
23 mai 2019
5 -
Salut,

Concernant, la remarque que tu as faite :

Une regexp qui matche à partir de la fin de ligne devrait utiliser le point d'ancrage $, donc quelque chose comme
if (/eau$/)
 au lieu de 
if(/eau\n/)

, à moins que tu veuilles tester quelque chose de particulier.

Je voulais regrouper dans un fichier les mots qui ont la même terminaison. Si je ne mets pas le caractère qui indique la fin de la ligne \n, il va insérer dans le fichier des mots qui possèdent la chaîne de caractères mais qui n’est pas à la fin du mot.

Par exemple, pour la chaîne "eau", et le fichier d’entrée suivant :

bateau
beauté
chameau

le programme va ajouter le mot beauté au fichier de sortie :

bateau
beauté
chameau

alors que le résultat désiré est

bateau
chameau

Merci pour tes conseils. Effectivement, j'ai vu dans plusieurs exemples l'emploi des lignes :

use strict;
use warnings;


Dorénavant, je vais ajouter ces deux lignes. Tant qu’à faire les choses, mieux vaut les faire correctement.

Aussi, merci pour les liens.

Je programme rarement en Perl ou en tout autre langage. Je m’y connais très peu. Cependant, Perl s’est avéré très utile pour la tâche que je voulais faire.

Je vais mettre à jour mes notes sur Perl. Encore merci.
[Dal]
Messages postés
5106
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
22 mai 2019
771 -
De rien, Perl est très pratique et puissant pour traiter du texte :-)

Pour clarifier,
$
dans une regexp permet d'ancrer l'expression à la fin de la chaîne, indépendamment des caractères utilisés par le format de fichier texte sur tel ou tel système pour indiquer un retour à la ligne.

if (/eau$/)
réalise donc ce que tu veux, sans que tu aies à préciser un caractère de retour à la ligne, et signifie "matche la suite de caractères 'eau' à partir de la fin".

Un autre point d'ancrage utilisable avec les regexp est
^
, qui signifie le début de la chaîne.

Ainsi, avec ta liste une regexp comme
/^ch/
appliquée sur les lignes :

automne
bateau
brise
chameau
cheval
gâteau

permettrait de matcher les lignes commençant par les lettres "ch" :

chameau
cheval

Pour plus d'infos, le tutoriel officiel de Perl est : https://perldoc.perl.org/perlretut.html

Dal
artagon7
Messages postés
261
Date d'inscription
dimanche 6 novembre 2005
Statut
Membre
Dernière intervention
23 mai 2019
5 -
Tu écris : Perl est très pratique et puissant pour traiter du texte

Je m'en étais rendu compte! ;-)

Je vais télécharger les tutos sur le site officiel que tu as donné comme référence. Je vais être à jour. Merci
Commenter la réponse de [Dal]
Messages postés
261
Date d'inscription
dimanche 6 novembre 2005
Statut
Membre
Dernière intervention
23 mai 2019
5
0
Merci
Bonjour,

Comme tu l'as mentionné dans le message précédent, le caractère $ seul, permet d'ancrer l'expression à la fin de la chaîne. Il devient inutile d'ajouter les caractères symbolisant le retour de ligne à la fin.

Voici le code complet pour ce petit programme :

#!/usr/bin/perl

use strict;
use warnings;

open(FICHIER_ENTREE, "entree.txt") or die "Le fichier ne s'ouvre pas: $!";
open(FICHIER_SORTIE, ">>sortie.txt") or die "Le fichier ne s'ouvre pas: $!";
open(FICHIER_ENTREE_MODIFIEE, ">>entree_modifiee.txt") or die "Le fichier ne s'ouvre pas: $!";

while(<FICHIER_ENTREE>)
{
if (/eau$/) {print FICHIER_SORTIE "$_"}
else {print FICHIER_ENTREE_MODIFIEE "$_"};
}

close FICHIER_ENTREE;
close FICHIER_SORTIE;
close FICHIER_ENTREE_MODIFIEE;
Commenter la réponse de artagon7