dir_file_updater.pl 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 04 November 2012
  5. # https://github.com/trizen
  6. # Update files in a directory, with files from other dirs.
  7. # Example: perl dir_file_updater.pl -o /tmp /root
  8. # /tmp/file.txt is updated with the newest file from the /root dir,
  9. # or it's sub-directories, called file.txt, but only if the file is newer
  10. # than the file from the /tmp dir. This script updates only the files from
  11. # the OUTPUT_DIR, without checking it's sub-directories.
  12. use 5.010;
  13. use strict;
  14. use warnings;
  15. use File::Copy qw(copy);
  16. use File::Find qw(find);
  17. use Getopt::Std qw(getopts);
  18. use File::Compare qw(compare);
  19. use File::Spec::Functions qw(rel2abs catfile);
  20. my %opts;
  21. getopts('o:', \%opts);
  22. sub usage {
  23. die <<"EOH";
  24. usage: $0 [options] [dirs]
  25. options:
  26. -o <output_dir> : update files in this directory
  27. example: $0 -o /my/path/out /my/path/input
  28. EOH
  29. }
  30. my $output_dir = $opts{o};
  31. if ( not defined $output_dir
  32. or not -d $output_dir
  33. or not @ARGV) {
  34. usage();
  35. }
  36. $output_dir = rel2abs($output_dir);
  37. my %table;
  38. sub update_files {
  39. my $file = $File::Find::name;
  40. return unless -f $file;
  41. if (not exists $table{$_} or -M ($table{$_}) > -M ($file)) {
  42. $table{$_} = $file;
  43. }
  44. }
  45. my @dirs;
  46. foreach my $dir (@ARGV) {
  47. if (not -d -r $dir) {
  48. warn "[!] Invalid dir '$dir': $!\n";
  49. next;
  50. }
  51. push @dirs, rel2abs($dir);
  52. }
  53. find {wanted => \&update_files,} => @dirs;
  54. opendir(my $dir_h, $output_dir)
  55. or die "Can't read dir '$output_dir': $!\n";
  56. while (defined(my $file = readdir($dir_h))) {
  57. next if $file eq q{.} or $file eq q{..};
  58. my $filename = catfile($output_dir, $file);
  59. next unless -f $filename;
  60. if (exists $table{$file}) {
  61. if (-M ($table{$file}) < -M ($filename)
  62. and compare($table{$file}, $filename) != 0) {
  63. say "Updating: $table{$file} -> $filename";
  64. copy($table{$file}, $filename) or do { warn "[!] Copy failed: $!\n" };
  65. }
  66. }
  67. }
  68. closedir $dir_h;