2

名前を変更したい 96 個のファイルを含むフォルダーがあります。問題は、各ファイル名に一意の変更が必要なことです...各名前の前にゼロを追加したり、拡張子を変更したりするのとは異なります。検索と置換を行うのは現実的ではありません。変更したい名前の例を次に示します。

newSEACODI-sww2320H-sww24_07A_CP.9_sww2320H_sww2403F.fsa
newSEACODI-sww2320H-sww24_07B_CP.10_sww2320H_sww2403F.fsa
newSEACODI-sww2320H-sww24_07C_CP.11_sww2320H_sww2403F.fsa
newSEACODI-sww2320H-sww24_07D_CP.12_sww2320H_sww2403F.fsa
newSEACODI-sww2320H-sww24_07E_R.1_sww2320H_sww2403F.fsa
newSEACODI-sww2320H-sww24_07F_R.3_sww2320H_sww2403F.fsa
newSEACODI-sww2320H-sww24_07G_R.4_sww2320H_sww2403F.fsa
newSEACODI-sww2320H-sww24_07H_R.5_sww2320H_sww2403F.fsa

perl を使用して、上記の名前をそれぞれ以下の名前に変更したいと思います。

SEACODI_07A_A.2_sww2320H_2403F.fsa
SEACODI_07B_A.4_sww2320H_2403F.fsa
SEACODI_07C_H.1_sww2320H_2403F.fsa
SEACODI_07D_H.3_sww2320H_2403F.fsa
SEACODI_07E_H.6_sww2320H_2403F.fsa
SEACODI_07F_H.7_sww2320H_2403F.fsa
SEACODI_07G_Rb.4_sww2320H_2403F.fsa
SEACODI_07H_Rb.9_sww2320H_2403F.fsa

そのようなことはできますか?新しい名前のリストを含むテキスト ファイルを作成し、そのリストを @newnames と呼ぶという漠然とした考えがあります。現在のファイル名から別の配列を作成し、@oldnames と呼びます。次に、@oldnames のfor各要素 $i が @newnames の対応する $i に置き換えられるループを実行します。

ただし、現在のファイル名から配列を作成する方法がわからないため、この漠然としたアイデアが正しい方向に進んでいるかどうかはわかりません。「oldnames」という名前のディレクトリに、めちゃくちゃな名前のファイルを保管しています。以下は、そのディレクトリ内のファイル名から配列を作成しようとする私の試みです:

#!/usr/bin/perl -w
use strict; use warnings;

my $dir = 'oldnames';
opendir ('oldnames', $dir) or die "cannot open dir $dir: $!";
my @file = readdir 'oldnames';
closedir 'oldnames';

print "@file\n";

上記は何もしていないようでした。道に迷いました。ヘルプ?

4

3 に答える 3

1

ここ:

#!/usr/bin/perl
use warnings;
use strict;

use autodie;
use File::Copy;

# capture script name, in case we are running the script from the 
# same directory we working on. 
my $this_file = (split(/\//, $0))[-1];
print "skipping file: $this_file\n";

my $oldnames = "/some/path/to/oldnames";
my $newnames = "/some/path/to/newnames";

# open the directory
opendir(my $dh, $oldnames); 

# grep out all directories and possibly this script. 
my @files_to_rename = grep { !-d && $_ ne $this_file } readdir $dh;
closedir $dh;

### UPDATED ###
# create hash of file names from lists:
my @old_filenames = qw(file1 file2 file3 file4);
my @new_filenames = qw(onefile twofile threefile fourfile);
my $filenames = create_hash_of_filenames(\@old_filenames, \@new_filenames);
my @missing_new_file = ();  


# change directory, so we don't have to worry about pathing
# of files to rename and move... 
chdir($oldnames);
mkdir($newnames) if !-e $newnames;


### UPDATED ###
for my $file (@files_to_rename) {
    # Check that current file exists in the hash,
    # if true, copy old file to new location with new name
    if( exists($filenames->{$file}) ) { 
        copy($file, "$newnames/$filenames->{$file}");
    } else {
        push @missing_new_file, $file;
    } 
}


if( @missing_new_file ) { 
    print "Could not map files:\n", 
        join("\n", @missing_new_file), "\n";
}

# create_hash_of_filenames: creates a hash, where
# key = oldname, value = newname
# input: two array refs 
# output: hash ref 
sub create_hash_of_filenames {
    my ($oldnames, $newnames) = @_; 
    my %filenames = (); 

    for my $i ( 0 .. (scalar(@$oldnames) - 1) ) { 
        $filenames{$$oldnames[$i]} = $$newnames[$i];
    }

    # see Dumper output below, to see data structure
    return \%filenames;
}

ダンパーの結果:

$VAR1 = {
  'file2' => 'twofile',
  'file1' => 'onefile',
  'file4' => 'fourfile',
  'file3' => 'threefile'
};

実行中のスクリプト:

$ ./test.pl 
skipping file: test.pl
Could not map files:
a_file.txt
b_file.txt
c_file.txt

ファイルの結果:

$ ls oldnames/
a_file.txt
b_file.txt
c_file.txt
file1
file2
file3
file4

$ ls newnames/
fourfile
onefile
threefile
twofile
于 2013-07-16T05:32:39.410 に答える
0

あなたのコードは少し奇妙ですが、うまくいくはずです。ディレクトリ「oldnames」またはその上のディレクトリで実行していますか? その上のディレクトリにいる必要があります。より標準的な書き方は次のようになります。

#!/usr/bin/perl -w
use strict; use warnings;

my $dir = 'oldnames';
opendir ( my $oldnames, $dir) or die "cannot open dir $dir: $!";
my @file = readdir $oldnames;
closedir $oldnames;

print "@file\n";

これにより、 「.」を含む のすべて@filesファイルが取り込まれます。と '..'。名前の変更方法によっては、それらを除外する必要がある場合があります。oldnames

于 2013-07-15T23:53:31.367 に答える