in reply to Re^2: Optimizing files' moving with File::Find & File::Copy modules
in thread Optimizing files' moving with File::Find & File::Copy modules

system "find $dir1 -type f -exec mv -t $dir2 '{}' '+'";
Spaces and special characters aren't a problem as find doesn't invoke a shell. And by using a + instead of a ;, the -exec will behave as xargs.

You may need GNU implementations of find and mv, I do not know whether mv -t is a POSIX requirement, nor do I know that of find -exec command . But I doubt it's much of a problem to get those GNU tools running on a platform that supports perl.

  • Comment on Re^3: Optimizing files' moving with File::Find & File::Copy modules
  • Download Code

Replies are listed 'Best First'.
Re^4: Optimizing files' moving with File::Find & File::Copy modules
by runrig (Abbot) on Nov 17, 2009 at 17:16 UTC
    If he doesn't have that implementation of find, and there are spaces in filenames, the array form of system will handle them:
    my @files = <$dir1/*>; system("mv", @files, $dir2);
      Eh, no. <$dir1/*> doesn't distinguish between files and directories, it doesn't find files whose name start with a dot, and doesn't recurse into directories below $dir1. And if there are many files, you may run into system limits - most OSses have a limit on the number of arguments (and total size of the arguments) exec can take. (E2BIG).
        So I simplified "finding" the files :-) (as you did in your first answer...and before I read the followup about needing a recursive find...and if a single level was adequate but you needed to filter directories, then a simple grep could take care of that...and if you really wanted files with leading dots, then add a ".*" pattern to the glob) You could use File::Find to push the files onto an array, then splice off N files at a time and use system to move the files.