我正在尝试使用在Perl中编写的here脚本,但它会遇到错误。我已经联系了作者,但还没有回复。我希望你能帮助我。
错误如下:
错误:无法将/home/bruno321/.config/Clementine/albumcovers/271b13967f57caba893b366730337fb03439c60a.jpg复制到/ media / mp3_1 / Musica / Amarok / 2%20Lone%20Swordsmen / A%20Bag%20of%20Blue%20Sparks /。错误:文件或目录不存在
我认为错误在于处理空格,因为在没有空格的目录中它运行正常,但它不会将文件重命名为“cover.jpg”,因为我相信脚本打算这样做(和我当然需要这样做)。
#!/usr/bin/perl
use strict;
use warnings;
use Carp;
use DBI;
use strict;
use Data::Dumper;
use File::Basename;
use File::Copy;
my $db_filename = shift(@ARGV);
$db_filename
|| croak
"missing mandatory param: sqlite filename\n(try ~/.config/Clementine/clementine.db\n";
if ( !-f $db_filename ) {
croak "no such database file: $db_filename\n";
}
my $force_rewrite = shift(@ARGV) || 0;
my $dbh =
DBI->connect( "dbi:SQLite:$db_filename", q{}, q{},
{ 'RaiseError' => 1, 'AutoCommit' => 1 } );
my $query = q{SELECT artist,album, art_automatic,art_manual,filename
FROM songs WHERE art_manual IS NOT NULL GROUP BY(album) ORDER BY artist};
my $sth = $dbh->prepare($query);
$sth || croak 'prepare error: ' . $dbh->errstr . "\n";
$sth->execute || croak 'execute error: ' . $dbh->errstr . "\n";
my %treated = ();
while ( my $res = $sth->fetchrow_hashref ) {
( undef, my $dest_dir, undef ) = fileparse( $res->{'filename'} );
next if $treated{$dest_dir};
$treated{$dest_dir}++;
# strip leading file:// -> should do this better
$dest_dir =~ s/^file:\/\///g;
my $dest_file = $dest_dir . 'cover.jpg';
# unless we are given overwrite option, skip dirs that have covers
if ( !$force_rewrite ) {
next if ( -f $dest_file );
}
#print "CMD: cp $res->{'art_manual'} $dest_file\n";
copy( $res->{'art_manual'}, $dest_dir )
|| printf( "ERROR: unable to copy %s to %s. error: %s\n",
$res->{'art_manual'}, $dest_dir, $! );
}
exit;
答案 0 :(得分:7)
显然$dest_dir
是URL编码的,您需要它是文字的。换句话说,在修剪file://
前缀后,您需要将任何%NN
十六进制转义符解码为相应的文字字符。见Using Perl, how do I decode or create those %-encodings on the web?基本上,你想要
use URI::Escape 'uri_unescape';
然后
$dest_dir = uri_unescape($dest_dir);
此外,您正在创建$dest_file
,但忽略它并将文件复制到$dest_dir
。
作为一个额外的风格问题,警告和错误应该发送到stderr,而不是stdout。