Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2975 connectés 

  FORUM HardWare.fr
  Programmation
  Shell/Batch

  Création automatique de dossier

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Création automatique de dossier

n°2264692
maaon
Posté le 23-08-2015 à 09:41:40  profilanswer
 

Bonjour, je cherche un script ou un logiciel qui me permettrait lorsque je l’exécuterai dans un dossier de créer des dossiers portant comme nom la date de création des fichiers (2015.08.23 par exemple) contenus dans le dossier et déplaçant chaque fichier inclus dans chaque dossier correspondant à la date de création.
 
Je précise que je ne comprend rien en programmation.
 
Merci

mood
Publicité
Posté le 23-08-2015 à 09:41:40  profilanswer
 

n°2264698
rat de com​bat
attention rongeur méchant!
Posté le 23-08-2015 à 14:29:23  profilanswer
 

Sous quel OS? Je suppose Windows car apparemment sous Linux il n'y a pas de date de création sauvegardée pour les fichiers...

 

Voici un truc en Perl bricolé à la va vite, absolument sans garantie, mais qui fonctionne bien chez moi sous XP (oui oui, très vieux  :o ). Faire valider par un pro et/ou tester intensément avant de l'utiliser en prod!

 

bug connu: ne gère pas les raccourcis, je suppose qu'il y en a pas...

 

Pour utiliser installer StrawberryPerl (ou ActiveStatePerl mais j'ai pas testé), sauvegarder le script sous script.pl dans le dossier où il y a les fichiers à traiter puis lancer perl script.pl en ligne de commande (ou créer un raccourci).

 

Si il y a beaucoup de fichiers on peut virer l'affichage, soit les deux print.

 
Code :
  1. use strict;
  2. use warnings FATAL => 'all';
  3. use autodie;
  4. use File::Copy; #copy() et move()
  5.  
  6. #!SANS GARANTIE!
  7.  
  8. #http://perldoc.perl.org/perlport.html
  9. #stat: [...] ctime is creation time instead of inode change time (Win32).
  10.  
  11. opendir DH, '.';
  12.  
  13. my $file;
  14.  
  15. while(($file=readdir DH))
  16. {
  17.    next if($file eq 'script.pl'); #à ajuster si changement de nom, faut pas que le script essaye de se déplacer lui-même...
  18.    next if(!-f $file); #si c'est un dossier on l'ignore
  19.    
  20.    print "file \"$file\" --> ";
  21.    
  22.    my @t=localtime((stat($file))[10]); #sortir la date de création au format UNIX et convertir
  23.  
  24.    my $age=sprintf("%04d.%02d.%02d", $t[5]+1900, $t[4]+1, $t[3]); #et mettre dans le bon format
  25.  
  26.    print "$age\n";
  27.    
  28.    if(!-e $age)
  29.    {
  30.        mkdir $age;
  31.    }
  32.    elsif(!-d $age)
  33.    {
  34.        die "erreur: le nom \"$age\" est déjà utilisé par un fichier!";
  35.    }
  36.    
  37.    if(-f $age.'\\'.$file)
  38.    {
  39.        die "erreur: collision: \"$file\" existe déjà dans dossier $age";
  40.    }
  41.    
  42.    copy($file, $age.'\\'.$file); #copy() pour copier ou move() pour déplacer
  43. }
  44.  


Message édité par rat de combat le 23-08-2015 à 14:32:37
n°2264701
maaon
Posté le 23-08-2015 à 17:25:45  profilanswer
 

Merci énormément, le programme fonctionne parfaitement.


Message édité par maaon le 23-08-2015 à 17:35:54
n°2264702
maaon
Posté le 23-08-2015 à 17:51:22  profilanswer
 

Par contre, comment faire si je veux que le script traite également les sous répertoires ?

n°2264704
rat de com​bat
attention rongeur méchant!
Posté le 23-08-2015 à 20:11:31  profilanswer
 

Est-ce que les sous-répertoires peuvent contenir à leur tour des sous-répertoires? Si oui jusqu'à quelle profondeur? Faut-il créer le dossier qui porte la date d'un ou plusieurs fichiers à l'endroit où se trouve le fichier ou plutôt à la racine du truc (là où se trouve le script)? Décris avec précision ce que tu as et ce que tu veux obtenir. Par contre je promets rien, faudra voir si j'ai le temps...

n°2264705
gilou
Modérateur
Modzilla
Posté le 23-08-2015 à 20:30:06  profilanswer
 

Pour ce genre de truc, il y a un module de base standard en perl, File::Find
 
J'aurais fait un script de ce genre:

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use autodie;
  5.  
  6. use File::Basename;
  7. use File::Find;
  8. use File::stat;
  9.  
  10. $::PROGRAM = basename $0;
  11.  
  12. sub creation_date {
  13.  my $i = 0;
  14.  my @cdate = map {$_ + (0, 1, 1900)[$i++]} (localtime(stat(shift)->ctime))[3..5];
  15.  return sprintf("%04d.%02d.%02d", reverse @cdate);
  16. }
  17.  
  18. sub process {
  19.  if (-f) {
  20.    my $file = $_;
  21.    # on ne traite pas un fichier de même nom que le script
  22.    return if (/^$::PROGRAM$/);
  23.    # on récupère la date de création au format adéquat
  24.    my $cdate = creation_date($file);
  25.    # on ne fait rien si le fichier est déjà dans le bon répertoire
  26.    return if (basename($File::Find::dir) eq $cdate);
  27.    # Arrêt si le répertoire ne peut être créé à cause d'un fichier de même nom
  28.    die "Erreur: le nom '$cdate' est déjà utilisé par un fichier!" if (-f $cdate);
  29.    # On crée le répertoire s'il n'existe pas
  30.    mkdir $cdate unless (-d $cdate);
  31.    # Arrêt si le fichier existe déjà dans le répertoire
  32.    die "Erreur: collision: '$file' existe déjà dans le dossier $cdate!" if (-f $cdate.'/'.$file);
  33.    # on effectue le déplacement du fichier dans le répertoire
  34.    rename $file, $cdate.'/'.$file;
  35.  }
  36. }
  37.  
  38. find({ bydepth => 1, wanted => \&process, follow => 1 }, '.');


(pas testé au delà d'un cas simple avec quelques fichiers, mais ça me semble OK).
Si on veut un message plus explicite pour les messages de sortie en erreur, on peut faire:
die "Erreur: le nom '$cdate' est déjà utilisé par un fichier dans le répertoire $File::Find::dir!"
et
die "Erreur: collision: '$file' existe déjà dans le dossier $File::Find::dir\\$cdate"
 
A+,
 
P.S. pour le rongeur combatif, je ne sais pas si tu connaissais l'idiome employé dans le map, qui sert a ajuster une liste numérique retournée par une fonction, mais il est assez sympa.

Message cité 1 fois
Message édité par gilou le 23-08-2015 à 22:23:36

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2264706
rat de com​bat
attention rongeur méchant!
Posté le 23-08-2015 à 21:10:52  profilanswer
 

gilou a écrit :

Pour ce genre de truc, il y a un module de base standard en perl


Il y a un module pour à-peu-près tout en Perl, mais faut le savoir (et faut savoir l'utiliser)... Honnêtement pour moi personnellement j'utilise toujours un truc du genre

Code :
  1. system('dir * /a-d /b > liste');
  2. open(IN, 'liste', '<');
  3. while(($fichier=<IN> ))
  4. ...


 :o

 
Citation :


my @cdate = map {$_ + (0, 1, 1900)[$i++]} (localtime(stat(shift)->ctime))[3..5];

 

P.S. pour le rongeur combatif, je ne sais pas si tu connaissais l'idiome employé dans le map, qui sert a ajuster une liste numérique retournée par une fonction, mais il est assez sympa.


Oulà... Ca c'est encore un truc de "Perl pro". Moi je fais du Perl pour débutant... ;-)

 
Citation :

$::PROGRAM = basename $0;


C'est quoi cette syntaxe $::XYZ?

 

Bon, à priori le problème est réglé...

Message cité 1 fois
Message édité par rat de combat le 23-08-2015 à 21:11:44
n°2264707
maaon
Posté le 23-08-2015 à 21:38:39  profilanswer
 

Effectivement, le problème est réglé. Ca m'a donné envie de me mettre à la programmation...
 
Merci beaucoup pour votre temps.

n°2264708
gilou
Modérateur
Modzilla
Posté le 23-08-2015 à 22:02:03  profilanswer
 

rat de combat a écrit :


Il y a un module pour à-peu-près tout en Perl, mais faut le savoir (et faut savoir l'utiliser)...


Tout a fait, mais File::Find fait partie des trucs très standard. C'est une transposition de la commande find unix
 

rat de combat a écrit :

Citation :

$::PROGRAM = basename $0;


C'est quoi cette syntaxe $::XYZ?

Ça permet d'avoir une variable globale sans faire hurler use strict; :D
Lorsqu'il rencontre  $::XYZ, l'interpréteur sait que c'est une variable dont la portée est le package $main ($:: est une abréviation pour $main::) bref que c'est une variable de package, qui est donc dans un autre namespace que les variables lexicales, pour lesquelles la portée est explicitement indiquée avec l'emploi de my, state, our ou local
 
A+,

Message cité 1 fois
Message édité par gilou le 01-09-2015 à 02:23:56

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2264709
gilou
Modérateur
Modzilla
Posté le 23-08-2015 à 22:26:08  profilanswer
 

Note: Pour que le code soit portable sous Unix & Co, j'ai remplacé les deux '\\' par deux '/' dans le code posté précédemment. Ça m'a sauté aux yeux en relisant.
 
A+,


Message édité par gilou le 23-08-2015 à 22:26:32

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
mood
Publicité
Posté le 23-08-2015 à 22:26:08  profilanswer
 

n°2265090
rat de com​bat
attention rongeur méchant!
Posté le 31-08-2015 à 16:21:42  profilanswer
 

gilou a écrit :


Tout a fait, mais File::Find fait partie des trucs très standard. C'est une transposition de la commande find unix


Moi je ne connais pas (toujours pas) Unix... :o (mais je finirai par m'y mettre, faudra bien)

 
gilou a écrit :

Ça permet d'avoir une variable globale sans faire hurler use strict; :D
Lorsqu'il rencontre  $::XYZ, l'interpréteur sait que c'est une variable dont la portée est le package $main ($:: est une abréviation pour $main::) bref que c'est une variable de package, qui est donc dans un autre namespace que les variables lexicales, pour lesquelles la portée est explicitement indiquée avec l'emploi de my, state, our ou local


Merci pour l'explication!


Message édité par rat de combat le 31-08-2015 à 16:22:23

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Shell/Batch

  Création automatique de dossier

 

Sujets relatifs
Création pdf avec envoi mail (TCPDF)Désactiver saisie semi automatique sur un champs HTML (Chrome)
Création d'une sous gallerie d'imagesCreation d'un site web de façon simplifié
Comment générer des images de 256 px par 240 px de façon automatiqueCréation musical grâce aux jeux ; Mais lesquels ?
Création d'un bootloaderJADE : création / destruction Agents
Batch création automatique dossier (xcopy)Vista : création automatique d'un dossier compressé
Plus de sujets relatifs à : Création automatique de dossier


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR