bonjour,
j'ai un problème...
j'arrive pas à faire un script qui supprime des fichiers suivant leurs extensions... les noms de fichier peuvent être différent...
voilà, si quelqu'un à une idée ?
bonjour,
j'ai un problème...
j'arrive pas à faire un script qui supprime des fichiers suivant leurs extensions... les noms de fichier peuvent être différent...
voilà, si quelqu'un à une idée ?
Bonjour,
le mieux est que tu nous montre ton script, on te dira si ça cloche quelque part
Bin en fait j'ai fait ce script en batch et je voudrais le refaire en perl...
ça c'est la première partie de mon problème...SET line=C:\Test_batch\test\
del %line%*.l*
del %line%*.page
del %line%*.BCS
del %line%*.db
del %line%*.dbb
del %line%*.esav
del %line%*.full
del %line%*.osav
del %line%*.PVTS
del %line%*.r*
del %line%*.s*
j'arrive pas à "traduire" ça en perl...
la 2ème partie de mon problème c'est que j'aimerai que ce script supprime les fichier dans tout les sous-dossier du dossier de travail...
je ne vois pas comment (ni en batch ni en perl) je peux lui dire : "fais ça dans tout les sous-dossier"...
Voili
T'as pensé à une fonction recursive?
Bon je te mache un peu le travail mais ca marche comme ca : la fonction debute son analyse sur un repertoire passé en argument
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 sub ParseDirectory { my $directory = shift if (-d $_[0]) or return 0; $directory = $directory."/" if ( $directory !~ /\/$/ ) ; opendir DIR, $directory or print "Impossible d'ourvrir le dossier $FILE\n", return 0; my @a_file = readdir DIR or return 0; @a_file = sort (@a_file); for (my $i=0; $i<scalar(@a_file); $i++){ my $tmp = $directory.$a_file[$i]; if ($tmp !~ /[\.~]$/) { if (-f $tmp) { &_ParseClasses($tmp); } elsif (-d $tmp) { &ParseDirectory($tmp); } } } close DIR; return 1; }
- si c'est un fichier elle execute une commande (ici _ParseClasses())
- si c'est un repertoire, la fonction se rappele elle meme.
PS: c'est une fonction d'un de mes programmes, donc ca va pas marcher directement pour le tient, c'est juste un exemple de fonction recursive ... surrement assez mal écrite mais bon, c'est le principe qui est important
ok, je vois ce que tu veux dire...
c'est une boucle, en fait??
Début du script
si c'est un fichier --> on supprime
si c'est un dossier ---> on relance le script
et ça s'arrête quand ??
je vais essayer de décortiquer ton script et d'en garder le principal...
Merci beaucoup pour ton aide !!!
Ca s'arrete tout seul quand ca a parcouru l'ensemble de ton arborescence
Ce n'est pas une boucle, la récursion est différente de l'itération !!Envoyé par petibonohm
Sinon une solution légèrement différente :
Ce code fait usage du module File::Find (distribué avec Perl en standard) pour parcourir l'ensemble des fichiers du répertoire spécifié et de ses sous-répertoires et leur appliquer à chacun la fonction del_files_by_type avec le nom du fichier courant dans $_.
Code Perl : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 #!/usr/bin/perl use strict; use warnings; use File::Find; find( \&del_files_by_type, 'C:\Test_batch\test' ); sub del_files_by_type { if( not -d $_ and m/\.(?:l.*|page|BCS|dbb?|esav|full|osav|PVTS|r.*|s.*)$/ ){ unlink( $_ ); } }
--
Jedaï
Merci beaucoup jeune padawan, ça marche nikel....
mais j'aimerai mieux comprendre comment ça marche...
Et ce que l'on pourrait m'expliquer plus précisément comment marche File::Find ??
Merci ++
Pour File::Find, c'est très simple dès lors qu'on a déjà eu affaire à une logique de callback, consulte la documentation pour plus de détails.
(La documentation de Wikipedia est légèrement erronée, car elle ne prend pas en compte le fait que dans certains langage les callbacks sont aussi puissant qu'un passage d'objet en paramêtre grâce aux closures)
EDIT : Maintenant Wikipedia est légèrement corrigée.
Par ailleurs File::Find présente l'avantage d'être un module du CORE, mais dans le même style et légèrement plus facile à utiliser, ou plus élégant, tu as pas mal de modules intéressants, comme File::Finder ou File::Find::Rule, pour future référence.
--
Jedaï
heu j'ai rien compris.... un homme à la mer !!!!
je voulais savoir comment marchait File::Find syntaxiquement... histoire de le réutiliser ailleur...
je suis novice dans le language Perl, t'as du t'en appercevoir...
Merci++
La question n'est pas là... Qu'est ce que tu n'as pas compris ? As-tu vraiment lu attentivement les liens que je t'ai donné ? La documentation de File::Find explique comment l'utiliser, il n'y a rien de vraiment compliqué là dedans, à part la notion de callback, mais c'est bien pour ça que je t'ai donné un lien vers wikipedia !Envoyé par petibonohm
--
Jedaï
L'anglais c'est pas mon fort, je vais revoir ton doc....
Merci de ton aide !!
Pourquoi pas une fonction 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 sub _delete_files { # Ouvre le dossier opendir(DIR, "dossier") or die "Impossible d'ouvrir le répertoire"; # Récupère le nom de tout les fichiers dans le dossier my @files = readdir(DIR); close(DIR); foreach my $file ( @files ) { # Si le fichier est un .txt ou .exe etc... if ( $file =~ /\.(txt|exe|rpm|jpg)$/i ) { unlink = "dossier/$file"; # On supprime le fichier } } }
J'ai pensé exactement la même chose que toi au débutEnvoyé par mobscene
Mais cette solution ne permet pas de rechercher dans les sous-répertoires, or c'ets ce que petibonohm veut faire...
Pour petibonohm, il te faut utiliser la méthode finddepth qui applique la fonction passée en paramètre (premier paramètre passé explicitement) sur chaque fichier du répoertoire passé en paramtre (second paramètre passé explicitement), puis dans chaquefichers des sous-répertoire, et enfin sur les répertoires eux mêmes.
Une autre solution tiré des snippets
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 #!/usr/bin/perl -w use strict; use diagnostics; ListRep('chemin du répertoire'); sub ListRep { my ($dir) = @_; if (! -e $dir ) { print "Répertoire inconnu ($dir)."; return undef; } if (! -d $dir ) { print "$dir n'est pas un répertoire."; return undef; } if (! opendir( DIR, $dir) ) { print "Impossible d'ouvrir le répertoire $dir : $!."; return undef; } my @files = grep !/(?:^\.$)|(?:^\.\.$)/, readdir DIR; closedir DIR; print "\nFICHIERS CONTENUS:\n"; foreach my $file (@files) { # Si le fichier est un .txt ou .exe etc... if ( $file =~ /\.(txt|exe|rpm|jpg)$/i ) { unlink = "$dir/$file"; # On supprime le fichier } } # si ont est sous windows if ( $^O eq 'MSWin32' ) { foreach(@files) { if (-d $dir."\\".$_) { print "\n\nREPERTOIRE : ".$_."\n"; ListRep($dir."\\".$_); } } else { # C'est un Unix foreach(@files) { if (-d $dir."/".$_) { print "\n\nREPERTOIRE : ".$_."\n"; ListRep($dir."/".$_); } } } }
Merci les gars pour l'interêt que vous portez à ma "cause"Envoyé par Woufeil
la fonction find marche bien elle fait ce que j'avais besoin, mais finddepth je ne sais pas comme l'utiliser...
sinon fonction simple ou snippets, inconnue au bataillon, je débute dans le perl....
Merci
finddepth n'est pas nécessaire, finddepth fait la même chose que find mais pas dans le même ordre, dans ton cas c'est indifférent.Envoyé par petibonohm
Fonction simple = Une simple fonction (sous-entendu sans utiliser de module, c'est du français, pas du jargon d'informaticien, ne t'affole pas pour si peu !! )
Snippets = Petit bout de code utile ou instructif (vient de snip = couper), nous avons une collections de snippets dans l'un des sujet important du forum Perl.
Ma solution doit fonctionner, mais elle n'est pas très instructive, sinon dans le fait que Perl fournit souvent des façons simple et efficace de faire les choses.
Si tu es en train d'apprendre Perl, essaie plutôt de comprendre cette fonction :
--
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
30
31
32
33
34
35
36 #!/usr/bin/perl use strict; use warnings; # sens toi libre de lui donner un nom plus pratique !! sub parcoure_rep_et_supprime_fichiers { # Récupère le répertoire donné en paramètre my $dir_path = shift; # Abandonne "sauf si" (unless) $dir_path est un répertoire unless( -d $dir_path ) { warn "$dir_path n'est pas un répertoire !\n"; return; } # ouvre le répertoire pour pouvoir le parcourir opendir my($dir), $dir_path or die "Impossible de parcourir $dir_path : $!\n"; # dans cette boucle $file_name va prendre successivement la valeur # de chacun des fichiers (ou répertoires) présents dans $dir while( my $file_name = readdir $dir ) { # on ignore les pseudo-répertoires "." et ".." en sautant à l'itération # suivante de la boucle (avec "next") next if $file_name =~ m/^\.\.?$/; # si $file_name est un répertoire, on rappelle la fonction sur lui if( -d "$dir_path/$file_name" ){ parcoure_rep_et_supprime_fichiers( "$dir_path/$file_name" ); } # sinon, si $file_name correspond à l'une de tes extensions elsif( $file_name =~ m/\.(?:l.*|page|BCS|dbb?|esav|full|osav|PVTS|r.*|s.*)$/ ) { # on le supprime unlink( "$dir_path/$file_name" ); } } }
Jedaï
Ok merci pour ça, c'est sympas !!
une question : comment supprimer un fichier sans extension avec ce programme ?
est ce que si je mets rien entre | | (quel est le nom de ce caractère d'ailleur??)
Code : Sélectionner tout - Visualiser dans une fenêtre à part [...] |page|BCS|dbb?|esav|[rien]|full|osav| [...]
sinon que veut dire le "?" dans |dbb?|
Merci
La plupart du temps le "?" signifie "0 ou 1 autre caractere quelconque"
Si c'est dans une regex perl ca signifie que l'expression precedente doit etre presente "0 ou 1" fois.
| est parfois appelé "pipe" (à prononcer à l'anglaise païpe), il sert à indiquer une alternative (on matche soit un côté soit l'autre de | ).Envoyé par petibonohm
C'est un problème de regex, je te conseille la lecture de perlrequick pour un bref résumé des possibilités de base de Perl dans le domaine. Après cette lecture, tu comprendras que ma regex teste d'abord pour la présence, puis continue en vérifiant si ce qu'il y a après ce point nous convient, il ne suffit donc pas de mettre une alternative vide pour qu'elle accepte les fichiers sans extension, ça ne lui fait accepter que les fichiers dont le nom se termine par un point. Ce que tu veux c'est plutôt ça :Envoyé par petibonohm
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 m/ #début de la regex ^ #début de la chaîne [^\.] #tout sauf un point $ #fin de la chaîne | # OU \. #un point (?: #groupement non-capturant l.* #liste des extensions acceptées |page #... |BCS #... |dbb? |esav |full |osav |PVTS |r.* |s.* ) #fin de la liste $ #fin de la chaîne /x # /x rend les espaces et les commentaires insignifiants dans une regexCa veut dire que dbb? va matcher soit "db" soit "dbb", l'élément immédiatement précédant le ? peut-être matché une ou zéro fois (on préfère une si c'est possible).Envoyé par petibonohm
--
Jedaï
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager