我正在运行其他人为我写的Perl脚本,我注意到以下正则表达式似乎与我的名为“Film CD 1.avi”,“Film2 CD 1”的文件不匹配。 avi“等:
$name = (split (/[ ]*CD[ ]*1/i, $in_avi))[0];
任何人都知道我需要做些什么来纠正它?
/编辑:完整的代码是:
#!/usr/bin/perl
use strict;
########################################################################
# Configuration Details #
########################################################################
# Array of movies to convert
my @MOVIES_TO_CONVERT; # = ('The Figher', 'The Fifth Element');
# Directory where the split AVI files are stored
my $MOVIE_IN_PATH = 'D:\split';
# Directory where the combined AVI files will be stored
my $MOVIE_OUT_PATH = 'D:\combined';
# Full path to the avidemux executable
my $AVIDEMUX = 'C:\Program Files (x86)\Avidemux\avidemux.exe';
########################################################################
# Functions #
########################################################################
# Return an array of all the AVI files in the specified directory.
sub get_avis_in_directory
{
my $dh; # Directory handle
my $dir; # Current directory
my @avis; # Array of file names to return
opendir ($dh, $dir = shift) or die "Failed to open directory $dir: $!\n";
while (readdir $dh)
{
next if (/^\.{1,2}/);
$_ = $dir . "\\" . $_;
push (@avis, $_) if (-f $_ and /.*\.avi$/i);
}
closedir $dh;
return (@avis);
}
########################################################################
# Entry Point #
########################################################################
die "Input directory $MOVIE_IN_PATH does not exist!\n" unless (-d $MOVIE_IN_PATH);
die "Output directory $MOVIE_OUT_PATH does not exist!\n" unless (-d $MOVIE_OUT_PATH);
# This variable represents the actual names and paths of movies to be converted.
# It will either be built from the files specified in @MOVIES_TO_CONVERT manually, or
# built dynamically based on the files in the source and destination paths.
my @movies_formatted; # Array of hashes of movies to convert
if ($#MOVIES_TO_CONVERT == -1)
{
my @in_avis; # Array of AVI files in the input directory
my @out_avis; # Array of AVI files in the ouput directory
@in_avis = get_avis_in_directory ($MOVIE_IN_PATH);
@out_avis = get_avis_in_directory ($MOVIE_OUT_PATH);
for my $in_avi (@in_avis)
{
if ($in_avi =~ /.*[ ]*CD[ ]*1\.avi$/i)
{
my $rec; # Temporary hash variable
my $name; # Name of the move we are processing
$name = (split (/[ ]*CD[ ]*1/i, $in_avi))[0];
$name = (split (/$MOVIE_IN_PATH[\\\/]{1}/i, $name))[1];
for my $in_avi_2 (@in_avis)
{
if ($in_avi_2 =~ /^$MOVIE_IN_PATH\\$name[ ]*CD[ ]*2\.avi$/i)
{
$rec->{'part2'} = $in_avi_2;
last;
}
}
if (defined $rec->{'part2'})
{
for my $out_avi (@out_avis)
{
if ($out_avi =~ /$name\.avi$/i)
{
$rec->{'output'} = $out_avi;
last;
}
}
unless (defined $rec->{'output'})
{
$rec->{'part1'} = $in_avi;
$rec->{'output'} = "$MOVIE_OUT_PATH\\$name.avi";
push (@movies_formatted, $rec);
}
}
}
}
}
else
{
my $rec; # Temporary hash variable
for my $name (@MOVIES_TO_CONVERT)
{
$rec = {};
$rec->{'part1'} = "$MOVIE_IN_PATH\\$name CD 1.avi";
$rec->{'part2'} = "$MOVIE_IN_PATH\\$name CD 2.avi";
$rec->{'output'} = "$MOVIE_OUT_PATH\\$name.avi";
push (@movies_formatted, $rec);
}
}
for my $movie (@movies_formatted)
{
my $convert_cmd = "\"$AVIDEMUX\" --load \"" . $movie->{'part1'} . "\" --append \"" . $movie->{'part2'} . "\" --force-smart --save \"" . $movie->{'output'} . "\" --quit";
print "$convert_cmd\n";
die "Unable to convert $movie->{'output'}!\n" if (system "$convert_cmd");
}
来自http://www.neowin.net/forum/topic/1128384-batch-file-to-run-command-on-joining-video-files的xorangekiller脚本。
答案 0 :(得分:1)
以什么方式不起作用?
use warnings;
use strict;
while (<DATA>) {
my $in_avi = $_;
my $name = (split (/[ ]*CD[ ]*1/i, $in_avi))[0];
print "$name\n";
}
__DATA__
Film CD 1.avi
Film2 CD 1.avi
打印:
Film
Film2
答案 1 :(得分:1)
$MOVIE_IN_PATH
中的反斜杠通过将其插入到正则表达式中来删除。将两者 split
命令更改为
$name = (split(/\Q$MOVIE_IN_PATH\E[\\\/]{1}/i, $name))[1];
即。添加\Q
... \E
以转义任何正则表达式元字符。
你的朋友似乎并不是一个特别优秀的Perl程序员。您可能希望尝试使用此代码。
#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;
use File::Spec;
# Configuration Details
#######################
# Array of movies to convert
my @MOVIES_TO_CONVERT; # = ('The Fighter', 'The Fifth Element');
# Directory where the split AVI files are stored
my $MOVIE_IN_PATH = 'D:\split';
# Directory where the combined AVI files will be stored
my $MOVIE_OUT_PATH = 'D:\combined';
# Full path to the avidemux executable
my $AVIDEMUX = 'C:\Program Files (x86)\Avidemux\avidemux.exe';
sub get_avis_in_directory {
opendir my $dh, $MOVIE_IN_PATH or die $!;
return grep {
/\.avi$/ and -f File::Spec->catfile($MOVIE_IN_PATH, $_)
} readdir $dh;
}
-d $MOVIE_IN_PATH or die qq(Input directory "$MOVIE_IN_PATH" does not exist!\n);
-d $MOVIE_OUT_PATH or die qq(Output directory "$MOVIE_OUT_PATH" does not exist!\n);
my @movies_formatted; # Array of hashes of movies to convert
if (@MOVIES_TO_CONVERT) {
for my $name (@MOVIES_TO_CONVERT) {
my $rec = {};
$rec->{part1} = File::Spec->catfile($MOVIE_IN_PATH, "$name CD 1.avi");
$rec->{part2} = File::Spec->catfile($MOVIE_IN_PATH, "$name CD 2.avi");
$rec->{output} = File::Spec->catfile($MOVIE_OUT_PATH, "$name.avi");
push @movies_formatted, $rec;
}
}
else {
my @in_avis = get_avis_in_directory($MOVIE_IN_PATH);
for my $in_avi (@in_avis) {
next unless $in_avi =~ /^(.+?)\s*CD\s*1\.avi$/i;
my $name = $1;
my $rec = {};
$rec->{part1} = $in_avi;
($rec->{part2}) = grep /^\Q$name\E\s*CD\s*2\.avi$/i, @in_avis;
if ($rec->{part2}) {
$rec->{$_} = File::Spec->catfile($MOVIE_IN_PATH, $rec->{$_}) for qw/ part1 part2 /;
$rec->{output} = File::Spec->catfile($MOVIE_OUT_PATH, "$name.avi");
push @movies_formatted, $rec;
}
}
}
for my $movie (@movies_formatted) {
my $convert_cmd = sprintf '"%s" --load "%s" --append "%s" --force-smart --save "%s" --quit',
$AVIDEMUX, @{$movie}{qw/ part1 part2 output /};
print "$convert_cmd\n";
die "Unable to convert $movie->{'output'}!\n" if (system $convert_cmd);
}