如何使用 Perl 的 qx mv 文件到目录?



我想将专用文件移动到其当前文件夹的子文件夹中。这项工作(有一个专用文件):

qx/mv -v 'the name of the file' TRANS/; # TRANS is the subfolder at the same level as 'my file'

但以下不起作用:

while (defined($_ = <PODCASTS>)) {
if (/ d{1}.mp3$/) {
print $_;
qx/mv -f -v "$_" TRANS/;
die; # for testing on first occurrence
};
}

它给出(Ariane ...Tadjikistan 1.mp3是文件的实际名称):

mv: rename Ariane Zevaco autour des Musiciens populaires au Tadjikistan 1.mp3
to TRANS/Ariane Zevaco autour des Musiciens populaires au Tadjikistan 1.mp3: No such file or directory

我使用了许多引用变体,但都无济于事(给出了各种错误注释)。

直接的问题是,您没有从从文件句柄读取的行中删除尾随换行符。

也就是说,不要依赖shell解析,而是使用安全的方式将未经修改的参数传递给被调用的程序:

system(qw(mv -f -v --), $_, 'TRANS/');

注意:您将整行传递给命令,其中将包括行结束。你应该先chomp行。

引用perlfunc:

system LIST

如果LIST中存在不止一个自变量,或者,如果LIST是一个具有多个值的数组,则启动由带有参数的列表的第一个元素给出的程序由列表的其余部分给出。

在C语言中,程序的main()函数将用argc == 4调用,argv[2]将从Perl脚本接收$_的内容。


替代解决方案

对于这个简单的问题,你并不需要外壳。您可以简单地使用Perlrename()函数


奖金代码我建议重写您的代码,使其更符合Perl习惯:

use strict;
use warnings;
use POSIX qw(:sys_wait_h);
while (<PODCASTS>) {
if (/ d.mp3$/) {
chomp;
print "$_n";
system(qw(mv -f -v --), $_, 'TRANS/');
die "Can't execute "mv": $!n"
if $? < 0;
die '"mv" killed by signal '  . WTERMSIG($?)    . "n"
if WIFSIGNALED($?);
die '"mv" exited with error ' . WEXITSTATUS($?) . "n"
if WEXITSTATUS($?);
}
}

奖金代码2如何用Perl内置函数替换system('mv', ...)

my $target = "TRANS/$_";
# Emulate the "mv -f" option
unlink($target) || $!{ENOENT}
or die "unlink: $!n";
# same as "mv"
rename($_, $target)
or die "rename: $!n";