2009-10-13 12 views
0

J'ai un dossier appelé "Lib" dans mon lecteur, il contient de nombreux fichiers à l'intérieur et j'ai un problème que ce dossier "Lib" est là à bien d'autres endroits dans le lecteur. Mon script Perl doit copier le contenu du dossier « Lib » qui sont dernières mises à jour et collez-le dans le dossier « d: \ perl \ Latest_copy_of_Lib »Comment synchroniser deux répertoires avec Perl?

Par exemple, j'ai des dossiers Lib dans d:\functions, d:\abc, et beaucoup d'autres lieux. Je veux trouver la dernière copie de chaque fichier dans ces répertoires. Donc, si le fichier d:\functions\foo.txt a été modifié pour la dernière fois le 2009-10-12 et d:\abc\foo.txt a été modifié le 2009-10-13, je veux que la version dans d:\abc soit copiée dans le répertoire cible.

J'ai utilisé file :: find mais il recherche dans le répertoire entier et copie le contenu qui n'est pas la dernière copie.

Répondre

2

Vous devez utiliser File::Find pour créer un hachage de fichiers à déplacer. Ne placez le chemin d'accès à un fichier dans le hachage que si le fichier est plus récent que le chemin déjà stocké dans le hachage. Voici une implémentation simple. Remarque, il peut y avoir des problèmes sur la plate-forme Windows, je ne suis pas habitué à utiliser File::Spec pour travailler avec des fichiers et des chemins d'une manière multi-plateforme.

#!/usr/bin/perl 

use warnings; 
use strict; 

use File::Find; 
use File::Spec; 

my %copy; 

my @sources = qw{ 
    /Users/cowens/foo/Lib 
    /Users/cowens/bar/Lib 
    /Users/cowens/baz/Lib 
}; 

find sub { 
    my ($volume, $dir, $file) = File::Spec->splitpath($File::Find::name); 
    my @dirs     = File::Spec->splitdir($dir); 
    my @base     = ($volume); #the base directory of the file 
    for my $dir (@dirs) { 
     last if $dir eq 'Lib'; 
     push @base, $dir; 
    } 
    #the part that is common among the various bases 
    my @rest = @dirs[$#base .. $#dirs]; 
    my $base = File::Spec->catdir(@base); 
    my $rest = File::Spec->catfile(@rest, $file); 

    #if we don't have this file yet, or if the file is newer than the one 
    #we have 
    if (not exists $copy{$rest} or (stat $File::Find::name)[9] > $copy{$rest}{mtime}) { 
     $copy{$rest} = { 
      mtime => (stat _)[9], 
      base => $base 
     }; 
    } 
}, @sources; 

print "copy\n"; 
for my $rest (sort keys %copy) { 
    print "\t$rest from $copy{$rest}{base}\n"; 
} 
+0

salut il prend la copie de tout le contenu de la Lib et l'imprime. Ce n'est pas le cas si une mise à jour se produit dans le dossier Lib récemment, il ne doit prendre que cette copie seul. disons par exemple si un dossier Lib contient un fichier .txt alors je fais un changement dans d: \ abc \ Lib en plaçant b.txt dans ce chemin, il doit chercher en dir et ne prendre que b.txt depuis que j'ai enlevé a.txt et remplacé par b.txt dans ce chemin seul pas dans tous les chemins. – User1611

9

Je pense que vous venez de décrire rsync. À moins que vous ayez des exigences bizarres ici, je ne pense pas que vous ayez besoin d'écrire du code pour le faire. Je ne voudrais certainement pas atteindre Perl pour faire le travail que vous avez décrit.

+0

Peut-être est-il limité à utiliser uniquement perl pour le faire? Tout le monde n'est pas dans la même situation, où ils ont un accès immédiat à n'importe quel code open source sur le web. Personnellement, je dois accomplir une tâche similaire à rsync, mais en raison d'une supervision trop zélée, je ne peux pas utiliser autre chose que perl. – airbear

+0

Il semble certainement bizarre que quelqu'un vous fasse confiance à partir de zéro que d'utiliser un programme qui est pratiquement pare-balles, disponible dès maintenant, et souvent facilement installé. Je pense que beaucoup de ces cas (peut-être pas les vôtres) n'ont pas la motivation nécessaire pour atteindre des niveaux supérieurs de gestion. Dites-leur combien d'argent ils vont économiser. :) –

+0

Vous avez un point, et je ne pouvais vraiment pas être plus d'accord avec vous. Cela dit, certaines sociétés sont résolument intransigeantes à se comporter aussi inefficacement et inefficacement que possible. – airbear

0

Si vous pouvez standardiser sur un emplacement unique pour vos bibliothèques, puis utilisez une des options suivantes:

variable initialisée PERL5LIB Environnement et ajouter

use lib 'C:\Lib'; 

ou

perl -I C:\Lib myscript 

Tous de ceux-ci vous donneront une copie unique de votre répertoire lib que n'importe lequel de vos scripts pourra accéder.

Questions connexes