我填充了一个数组,其中包含文件扩展名为mp3
的所有文件以及包含所有m4a
文件的单独数组,如下所示
my @mp3filesarray = grep ( -f ,<*.mp3>);
my @m4afilesarray = grep ( -f ,<*.m4a>);
我想要做的是比较数组的文件名以查看是否存在匹配或部分匹配,如果存在,则将mp3文件和m4a文件复制到新的子目录中,以便我可以查看文件以确定我要保留哪个文件。我确信我需要使用正则表达式,但我不知道如何做到这一点。我很感激任何帮助。感谢。
答案 0 :(得分:3)
以下是我如何做到这一点。
use strict;
use warnings;
use File::Path qw(make_path);
use File::Copy qw(move);
my %seen;
while ( my $file = glob '*.{mp3,m4a}' )
{
++$seen{ substr($file, 0, length() - 4) };
}
for my $dupe ( grep { $seen{$_} > 1 } keys %seen )
{
make_path($dupe);
move("$dupe.$_", "$dupe/$dupe.$_" for (qw(mp3 m4a)); # Change / to \ if you're on Windows
}
我首先将所有以m4a或mp3结尾的文件全局化,然后将其剥离为没有扩展名的基本名称并将其哈希。然后我遍历任何重复项并将它们移动到自己的文件夹中。
正则表达式会过度,因为glob扩展语法比正则表达式限制得多。
此方法仅查找重复项,但唯一的区别是文件扩展名。要进行模糊匹配,您需要的技术与我使用的O(n)散列策略不同。
第一个while
循环也可以使用File::Basename::fileparse()
编写,如下所示:
while (my $file = glob '*.{mp3,m4a}')
{
my $name = fileparse($file, qr/ [.] [^.]* \z/x);
++$seen{$name};
}
答案 1 :(得分:0)
您要做的事情非常昂贵 - 为了寻找部分匹配,您需要将每个文件名与每个其他文件名进行比较。大概你不想将mp3列表相互比较,这使得 little 更容易。
我选择foreach
循环:
my %files;
foreach my $file ( glob ( '*.mp3 *.m4a' ) {
my ( $name, $type ) = ( $file =~ m/(\w+)\.(m[4p][a3])/ );
$files{$type}{$name}++;
}
foreach my $mp3_file ( keys %{ $files{'mp3'} } ) {
if ( $files{'m4a'} ) { print "Dupe detected: mp3_file\n"; next; }
foreach my $m4a_file ( keys %{ $files{'m4a'} } ) {
if ( $mp3_file =~ m/\Q$m4a_file/ ) { print "Partial match $mp3_file $m4a_file\n"; }
if ( $m4a_file =~ m/\Q$mp3_file/ ) { print "Partial match $m4a_file $mp3_file\n"; }
}
}
类似的东西 - 你正在对文件名做一个直接的子串比较 - 没有扩展名。你想用m4a到mp3比较做同样的事情。 (如果你准备将每个文件与每个文件进行比较而不依赖于扩展名,你可以简化一下,但你也增加了比较次数...当然,你保证至少有一个重复:))
答案 2 :(得分:0)
如果您的文件中没有任何数字(如1.mp3或a12b.m4a),那么这将有效:
use strict;
use warnings;
system("sudo mkdir review");
my (@spmp3,@spm4a);
my @mp3file=`ls | grep mp3`;
my @m4afile=`ls | grep m4a`;
for (my $i=0; $i<=$#mp3file; $i++)
{
@spmp3 = split (/\./, $mp3file[$i]);
}
for (my $j=0; $j<=$#m4afile; $j++)
{
push (@spm4a, split (/\./, $m4afile[$j]));
}
for (my $k=0; $k<=$#mp3file; $k=$k+2)
{
for (my $l=0; $l<=$#m4afile; $l=$l+2)
{
if ( $spmp3[$k] eq $spm4a[$l] )
{
system(" mv $spmp3[$k].mp3 $spm4a[$k].m4a ./review");
}
}
}