I'm beginning to love Perl, but I don't understand whats going on here.
why does this work
my @cmd = ();
push @cmd, 'find';
push @cmd, 'data/path/';
push @cmd, "-name";
push @cmd, '*.xml';
push @cmd, '-exec';
push @cmd, 'mv';
push @cmd, '{}';
push @cmd, 'junk/path/';
push @cmd, '\;';
say join (' ', @cmd);
system(join(' ', @cmd));
Output
find data/path/ -name *.xml -exec mv {} junk/path/ \;
No errors from find! While this does not work
my @cmd = ();
push @cmd, 'find';
push @cmd, 'data/path/';
push @cmd, "-name";
push @cmd, '*.xml';
push @cmd, '-exec';
push @cmd, 'mv';
push @cmd, '{}';
push @cmd, 'junk/path/';
push @cmd, '\;';
say join (' ', @cmd);
system(@cmd);
Output:
find data/path/ -name *.xml -exec mv {} junk/path/ \;
find: Missing argument for »-exec«.
system should be able to understand arrays. See here. When I copy the output into shell, there is no missing argument, it just works. But my script can't execute this.
In the second system call, you shouldn't escape the ;.
The -exec switch to find slurps arguments until it finds a ;. ; is interpreted by the shell as a command separator, so when you run find ... -exec from the command-line, you need to escape it, and in shell scripts you'll see the pattern
find ... -exec ... \;
In your second system call, you collect all of the arguments in an array and pass the array directly to system. In this case, Perl is not using the shell to interpret the command, and the find command sees the argument \; instead of ;, and the -exec switch gets confused.
All you need to say to get your system command to work is
...
push @cmd, ';';
...
system(@cmd);
mob pointed out the immediate problem with your system call, but there's a better way to do this. Instead of executing an external command, you can use File::Find::Rule, which has an interface that's very similar to the find utility:
use strict;
use warnings 'all';
use File::Copy;
use File::Find::Rule;
my $dest = '/foo/bar';
File::Find::Rule->file
->name('*.xml')
->exec( sub { move($_, $dest) or warn "move($_, $dest) failed: $!" } )
->in('.');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With