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 :

Supprimer dernier caractère


Sujet :

Langage Perl

  1. #1
    Futur Membre du Club
    Inscrit en
    Mars 2007
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 12
    Points : 9
    Points
    9
    Par défaut Supprimer dernier caractère
    Bonjour à tous

    je m'initie au langage perl et comme par hasard j'ai un petit exercice perso que j'ai besoin d'effectuer.

    La sauvegarde de mon répertoire Maildir m'a rajouté à la fin de chaque fichier du répertoire et sous répertoire le caractère ~.

    Je souhaiterais le supprimer sur tous les fichiers.

    Pour le moment j'ai tenté de créer un tableau avec le contenu des fichiersvia la FAQ.

    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
     
     
    #!/usr/bin/perl
     
    use strict;
     
    my($maildir) = '/home/maildir/damien/Maildir';
     
    sub lister_fichiers_recur {
            my ($repertoire) = $maildir;
            my @fichiers = ();
                    opendir (DIR , $repertoire) || die "impossible d'ouvrir le repertoire $repertoire\n";
                            while (<DIR>) {
                                    if ( -f "$_") {
                                            push (@fichiers, $_);
                                    }
                                    elsif ( -d "$_") {
                                            push (@fichiers, lister_fichiers_recur($_));
                                    }
                            }
                    closedir (DIR);
     
    #       print $fichiers."\n";
            return @fichiers;
    }
    Je me doute déjà que ce code contient des erreurs mais lesquelles?
    Sinon avez-vous une meilleur méthode?
    Merci pour votre aide

    Et donc ensuite je souhaiterais récupérer ce tableau pour supprimer le caractère sur tous les fichiers listés dans le tableau.


    Merci encore pour votre aide précieuse.

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Juste une ou deux remarques.

    Tu crées bien une liste de tous les fichiers (encore que, je vais y revenir) mais ta liste contient les chemins relatifs (le nom du fichier si tu préfères) et non pas le chemin absolu. Tu vas donc avoir de sacrés problèmes pour renommer.

    Mais tu as d'autres problèmes plus importants (au fait as-tu testé ton code ?par ce que là, il n'est pas du tout fonctionnel).

    Ta liste de fichiers devrait être déclaré avant l'appel à la fonction. Je te fais remarquer que ton return() ne sert à rien puisque tu n'exploites jamais le retour de lister_fichier(). D'autre part, tu ne lis pas l'argument de lister_fichier() : quelque soit le niveau d'appel $repertoire vaut $maildir !

    Si tu veux garder ta fonction telle qu'elle est, tu dois au minimum avoir :
    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 @fichiers;
    sub lister_fichiers_recur {
    	my $repertoire = shift;
    	opendir DIR , $repertoire 
    		or die "impossible d'ouvrir le repertoire $repertoire\n";
    	while (<DIR>) {
    		if ( -f "$_") {
    			push (@fichiers, $repertoir.'/'.$_);
    		}
    		elsif ( -d "$_") {
    			push (@fichiers, lister_fichiers_recur($repertoire.'/'.$_));
            }
    	}
    	closedir DIR;
    }
    Pour ton problème tu as intérêt à faire d'une pierre de coup, c'est à dire à renommer tes fichiers lors de la récursion. Je te montre une solution proche de la tienne (on peut faire plus simple).

    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
    #!/usr/bin/perl
    use strict;
    use warnings;
     
    # set start path
    my $startpath = shift || '.';						
     
    sub cleanpath {
    	# get argument
    	my $path = shift;
    	# open path or die
    	opendir my($dir), $path	
    		or die "Can't open $path : $!\n";				
    	# clean up
    	for (readdir $dir) { rename $_, $1 if (/(.*)~$/); }
    	# recurse trough directories
    	my @content = grep { -d "$path/$_" && $_ !~ /^\.\.?$/} readdir $dir;
    	closedir $dir;
    	for (@content) { cleanpath("$path/$_"); }
    }
     
    checkpath($startpath);
    Comme tu peux le deviner readdir renvoie la liste du contenu du répertoire lu. Le premier for itère cette liste. Le grep sert à sélectionner les répertoires et à éviter que la récursion tourne en rond (en excluant . et .. de la liste). Le dernier for lance la récursion sur chacun des répertoires. Dans tous les cas on compose les chemins.

    Je n'ai pas testé et j'ai écrit un peu à la va vite mais cela devrait le faire. L'idée est là.

    Fais des essais, réécris le tout à ta façon (c'est le seul moyen d'apprendre) et pose des questions si tu en as.

    PS Tu aurais dû poster dans Language, pas ici.

  3. #3
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Je corrige un peu le code vite fait d'Iblis :
    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
    #!/usr/bin/perl
    use strict;
    use warnings;
     
    # set start path
    my $startpath = shift || '.';						
     
    sub cleanpath {
    	local $_;
            # get argument
    	my $path = shift;
    	# open path or die
    	opendir my($dir), $path	
    		or die "Can't open $path : $!\n";				
    	# clean up
    	while ($_ = readdir $dir) { 
    		cleanpath("$path/$_") if -d "$path/$_";
    		rename "$path/$_", "$path/$1" if m/^(.*)~$/; 
    	}
    	closedir $dir;
    }
     
    cleanpath($startpath);
    --
    Jedaï

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Merci Jedaï.

    J'aurais dû tout mettre dans un while mais comme j'étais parti à corriger le script...

    Pourquoi faut-il localiser le $_ ? A cause des appels récursifs ? Perl ne les localisent-ils pas automatiquement.

    Une autre question : j'avais volontairement intercalé le closedir() afin que la récursion n'empile pas les ouvertures de répertoires. Est-ce inutile*(par exemple si on parcourt tout un disque depuis la racine) ?

  5. #5
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par iblis Voir le message
    Pourquoi faut-il localiser le $_ ? A cause des appels récursifs ? Perl ne les localisent-ils pas automatiquement.
    Non, avec le for() c'est le cas (encore que même dans ce cas je jouerais la sécurité), mais avec le while explicite ça ne l'est pas.

    Citation Envoyé par iblis Voir le message
    Une autre question : j'avais volontairement intercalé le closedir() afin que la récursion n'empile pas les ouvertures de répertoires. Est-ce inutile*(par exemple si on parcourt tout un disque depuis la racine) ?
    Ce n'est pas une mauvaise idée, je ne sais pas combien de répertoires peuvent être ouverts en même temps, mais c'est sans doute préférable d'éviter d'en ouvrir trop.

    De tout façon, un scipt professionnel devrait utiliser File::Find ou équivalent pour cette tâche, ce serait plus adapté.

    --
    Jedaï

Discussions similaires

  1. Supprimer dernier caractère d'une chaîne
    Par almoha dans le forum Langage
    Réponses: 2
    Dernier message: 08/03/2013, 20h41
  2. Supprimer le dernier caractère d'une string
    Par calagan99 dans le forum ASP.NET
    Réponses: 2
    Dernier message: 10/07/2007, 10h31
  3. Supprimer le dernier caractère "€"?
    Par wormseric dans le forum Langage
    Réponses: 3
    Dernier message: 04/06/2007, 16h52
  4. Réponses: 15
    Dernier message: 28/02/2007, 10h00
  5. [Chaines] Supprimer le dernier caractère
    Par Commodore dans le forum Langage
    Réponses: 1
    Dernier message: 27/06/2006, 09h35

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