我用文件扩展名为mp3的所有文件填充了一个数组,用所有m4a文件填充了一个单独的数组,如下所示
my @mp3filesarray = grep ( -f ,<*.mp3>);
my @m4afilesarray = grep ( -f ,<*.m4a>);我想要做的是比较数组的文件名,看看是否匹配或部分匹配,如果有,将mp3文件和m4a文件复制到新的子目录中,以便我可以查看这些文件以确定要保留的文件。我确信我需要为此使用正则表达式,但不确定如何执行此操作。如果有任何帮助,我将不胜感激。谢谢。
发布于 2014-08-15 04:53:35
下面是我将如何处理这个问题。
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)散列策略不同的技术。
也可以使用File::Basename::fileparse()编写第一个while循环,如下所示:
while (my $file = glob '*.{mp3,m4a}')
{
    my $name = fileparse($file, qr/ [.] [^.]* \z/x);
    ++$seen{$name};
}发布于 2014-08-15 04:37:37
您正在尝试做的事情是非常昂贵的-为了查找部分匹配,您需要将每个文件名与其他文件名进行比较。您可能不希望将mp3列表相互比较,这会使它更容易一些。
我会使用一个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的比较执行相同的操作。(如果您准备将每个文件与每个文件的扩展名独立地进行比较,则可以简化一些,但同时也增加了比较的数量……当然,您保证至少有一个副本:))
发布于 2014-08-15 05:18:37
如果文件中没有任何数字(如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");
    }
  }
}https://stackoverflow.com/questions/25316717
复制相似问题