md5_rename.pl 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #!/usr/bin/perl
  2. # Rename files to their MD5 hex value in a given directory (and its subdirectories).
  3. # Example:
  4. # "IMG_20231024_094115.jpg" becomes "571b4ba928ae62e103b54727721ebe56.jpg"
  5. use 5.036;
  6. use Digest::MD5 qw();
  7. use File::Find qw(find);
  8. use File::Basename qw(dirname basename);
  9. use File::Spec::Functions qw(catfile);
  10. sub md5_rename_file ($file) {
  11. open my $fh, '<:raw', $file or return;
  12. my $ctx = Digest::MD5->new;
  13. $ctx->addfile($fh);
  14. my $digest = $ctx->hexdigest;
  15. close $fh;
  16. my $dirname = dirname($file);
  17. my $basename = basename($file);
  18. if ($basename =~ s{^.*\.(\w+)\z}{$digest.$1}s) {
  19. ## ok
  20. }
  21. else {
  22. $basename = $digest;
  23. }
  24. my $new_file = catfile($dirname, $basename);
  25. if (-e $new_file) { # new file already exists
  26. return;
  27. }
  28. rename($file, $new_file) or return;
  29. return $basename;
  30. }
  31. my @dirs = @ARGV;
  32. @dirs || die "usage: $0 [files | dirs]\n";
  33. find(
  34. {
  35. wanted => sub {
  36. if (-f $_) {
  37. say ":: Renaming file: $_";
  38. my $basename = md5_rename_file($_);
  39. if (defined($basename)) {
  40. say "-> renamed to: $basename";
  41. }
  42. else {
  43. say "-> failed to rename...";
  44. }
  45. }
  46. },
  47. },
  48. @dirs
  49. );