undir.pl 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #!/usr/bin/perl
  2. # Author: Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 10th August 2014
  5. # Website: https://github.com/trizen
  6. # Move all the files from a directory's sub-directories into the main directory (with depth control)
  7. use 5.010;
  8. use strict;
  9. use warnings;
  10. use Getopt::Std qw(getopts);
  11. use File::Copy qw(move);
  12. use File::Find qw(find);
  13. use File::Basename qw(basename);
  14. use File::Spec::Functions qw(catfile splitdir);
  15. sub usage {
  16. my ($code) = @_;
  17. print <<"USAGE";
  18. usage: $0 [options] [dirs]
  19. options:
  20. -u : undir the files
  21. -d : delete empty directories
  22. -t int : depth limit (default: unlimited)
  23. example:
  24. $0 -u -t 2 /my/dir
  25. USAGE
  26. exit($code // 0);
  27. }
  28. getopts('udht:', \my %opt);
  29. $opt{h} && usage(0);
  30. my @dirs = grep { -d } @ARGV;
  31. @dirs || usage(2);
  32. foreach my $dir (@dirs) {
  33. my $depth = splitdir($dir);
  34. my %dirs;
  35. my @files;
  36. find(
  37. {
  38. no_chdir => 1,
  39. wanted => sub {
  40. return if $File::Find::dir eq $dir;
  41. if (defined $opt{t}) {
  42. return if (splitdir($File::Find::dir) - $depth > $opt{t});
  43. }
  44. $dirs{$File::Find::dir} //= 1;
  45. push @files, $_ if -f;
  46. }
  47. } => $dir
  48. );
  49. my $error = 0;
  50. foreach my $file (@files) {
  51. say $file;
  52. if ($opt{u}) {
  53. my $basename = basename($file);
  54. my $newfile = catfile($dir, $basename);
  55. if (-e $newfile) {
  56. warn "File `$basename' already exists in dir `$dir'...";
  57. ++$error;
  58. }
  59. else {
  60. move($file, $newfile) || do {
  61. warn "Can't move file `$file' to `$newfile': $!";
  62. ++$error;
  63. };
  64. }
  65. }
  66. }
  67. if ($error == 0 and $opt{d}) {
  68. foreach my $key (keys %dirs) {
  69. rmdir($key);
  70. }
  71. }
  72. }