gilou Modérateur Modzilla | Sethenssen a écrit :
Bonjour,
Cette commande shell:
find $TMP_DIR -mtime +7 -exec rm -f {} \;
Permet de supprimer tous les fichiers dont la date de créa/modif est supérieur à 7 jours.
Je voudrais simplement savoir si une personne peut me dire quel est son équivalence/traduction en langage PERL.
Merci d'avance,
++
|
Le truc rapide quand on veut faire executer une commande shell et en récupérer le résultat:
my $cmd = "find $TMP_DIR -mtime +7"; (ou bien, my $cmd = "find $TMP_DIR -mtime +7 -print"; si la précédente ne suffit pas)
my @files = qx{$cmd}; unlink @files;
ca peut probablement se faire en une ligne ainsi:
unlink qx{"find $TMP_DIR -mtime +7"};
mais c'est a tester.
Le seul désavantage, c'est qu'on execute un shell externe au lieu de tout faire depuis perl, et que ça va impacter légèrement sur les performances.
Le plus propre, c'est d'utiliser le module File::Find, et l'utilitaire find2perl ( http://search.cpan.org/~dapm/perl- [...] nd2perl.PL ) qui transforme une commande find en une procédure perl appellée comme premier argument du find de File::Find
si je fais (sur mon pc, sous windows, d'ou le C:\Perl\bin\perl.exe -w)
find2perl $TMP_DIR -mtime +7 -exec rm -f {} \;
ça me génère le script perl correspondant:
Code :
#! C:\Perl\bin\perl.exe -w eval 'exec C:\Perl\bin\perl.exe -S $0 ${1+"$@"}' if 0; #$running_under_some_shell use strict; use File::Find (); # Set the variable $File::Find::dont_use_nlink if you're using AFS, # since AFS cheats. # for the convenience of &wanted calls, including -eval statements: use vars qw/*name *dir *prune/; *name = *File::Find::name; *dir = *File::Find::dir; *prune = *File::Find::prune; sub wanted; sub doexec ($@); use Cwd (); my $cwd = Cwd::cwd(); # Traverse desired filesystems File::Find::find({wanted => \&wanted}, '$TMP_DIR'); sub wanted { my ($dev,$ino,$mode,$nlink,$uid,$gid); (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_)) && doexec(0, 'rm','-f','{}','\;'); } sub doexec ($@) { my @command = @_; # copy so we don't try to s/// aliases to constants for my $word (@command) { $word =~ s#{}#$name#g } if ($ok) { $| = 1; return 0 unless <STDIN> =~ /^y/; } }
|
Bon après, on peut adapter, afin d'intégrer ça a son propre code.
Typiquement, je virerais l'exec avant le use strict, et les alias avec des globales *name, *dir et *prune à priori.
En plus, le code de find2perl est assez ancien, je ne suis pas sur qu'il marche encore bien (File::Find::find n'accepte pas '$TMP_DIR' avec ma version, il faut le mettre dans un array ($TMP_DIR)).
Bon en élaguant, on voit que grosso modo, le script peut se réduire à:
Code :
#!/usr/bin/perl -w use strict; use warnings; use File::Find; # Traverse desired filesystems my $TMP_DIR = 'C:\Downloads'; #a remplacer par la valeur voulue dans son script File::Find::find(\&wanted, ($TMP_DIR)); sub wanted { }
|
Ce qui veut dire que si on veut intégrer ça dans un script, il suffit d'ajouter
use File::Find;
en tête de script avec les autres use, et ($TMP_DIR étant alors défini)
File::Find::find(\&deleteOldFiles, ($TMP_DIR));
La ou on veut que l' action soit effectuée dans son script, ainsi que la subroutine
sub deleteOldFiles {
unlink $_ if (-f && (int(-M _) > 7));
}
la ou on ajoute les subroutines (en fin de script, après le corps principal du script chez moi, mais ça pourrait être aussi en tête de script, avant le corps principal du script, c'est une question de style)
Bref :
Code :
..................... use File::Find; ..................... File::Find::find(\&deleteOldFiles, ($TMP_DIR)); ..................... sub deleteOldFiles { } .....................
|
Note pédagogique:
if (-f && (int(-M _) > 7)); c'est un idiome perl pour noter
if (-f $_ && (int(-M $_) > 7));
le premier $_ est omis car c'est la valeur par défaut, et le _ devant le -M indique qu'on reprend le même argument que pour l'opérateur précédent de test de fichier (le -f ici).
Ca marche aussi probablement (j'ai pas testé) en virant le $_ devant le unlink, car c'est la valeur par défaut, mais c'est à réserver à ceux qui aiment vivre dangereusement.
Bon, une dernière réduction, utilisant les subroutines anonymes:
Code :
..................... use File::Find; ..................... File:: Find:: find({wanted => sub {unlink $_ if (-f && (int(-M _ ) > 7))}}, ($TMP_DIR)); .....................
|
A+, Message édité par gilou le 15-11-2009 à 12:38:02 ---------------
There's more than what can be linked! -- Iyashikei Anime Forever! -- AngularJS c'est un framework d'engulé! --
|