-1

他の誰かが私のために書いた 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");
}

xorangekiller によるhttp://www.neowin.net/forum/topic/1128384-batch-file-to-run-command-on-joining-video-filesのスクリプト。

4

2 に答える 2

2

のバックスラッシュは$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);
}
于 2013-01-13T18:09:18.427 に答える
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
于 2013-01-13T17:24:16.823 に答える