3

reference_すべてのディレクトリとサブディレクトリにあるすべての*.bmpファイルの名前の前に文字列()を付けようとしています。初めてsilkスクリプトを実行すると、ディレクトリとサブディレクトリが作成され、各サブディレクトリの下に、各モバイルアプリケーションのシーンショットが.bmp拡張子付きで保存されます。

自動化されたsilkscriptを2回実行すると、すべてのサブディレクトリに*.bmpファイルが再度作成されます。スクリプトを2回実行する前に、すべての*.bmpの前に文字列を付けたいと思いますreference_

たとえばfirst_screen.bmpreference_first_screen.bmp次のようなディレクトリ構造になっています。

C:\Image_Repository\BG_Images\second
...
C:\Image_Repository\BG_Images\sixth

持っているfirst_screen.bmpfirst_screen.bmpファイルなど...

誰か助けてもらえますか?

すべての画像ファイル名の前に文字列を付けるにはどうすればよいreference_ですか?

スクリプトを2回実行すると、シルクのPerlスクリプトがサブディレクトリから両方の画像を取得し、両方をピクセルごとに比較します。私は以下のコードで試しています。このタスクを完了する方法を教えてください。

#!/usr/bin/perl -w
&one;

&two;

sub one {

    use Cwd;

    my $dir ="C:\\Image_Repository";
    #print "$dir\n";
    opendir(DIR,"+<$dir") or "die $!\n";
    my @dir = readdir DIR;
    #$lines=@dir;
    delete $dir[-1];
    print "$lines\n";
    foreach my $item (@dir)
    {
        print "$item\n";
    }
    closedir DIR;
}

sub two {

    use Cwd;

    my $dir1 ="C:\\Image_Repository\\BG_Images";
    #print "$dir1\n";
    opendir(D,"+<$dir1") or "die $!\n";
    my @dire = readdir D;
    #$lines=@dire;
    delete $dire[-1];
    #print "$lines\n";
    foreach my $item (@dire)
    {
        #print "$item\n";
        $dir2="C:\\Image_Repository\\BG_Images\\$item";
        print $dir2;
        opendir(D1,"+<$dir2") or die " $!\n";
        my @files=readdir D1;
        #print "@files\n";  
        foreach $one (@files)
        {
            $one="reference_".$one;
            print "$one\n";
            #rename $one,Reference_.$one;
        }
    }
    closedir DIR;
}

'+ <'モードでオープンコールを試しましたが、読み取りおよび書き込みモードでコンパイルエラーが発生します。このコードを実行すると、BG_imagesフォルダー内のファイルにプレフィックス付きの文字列が表示されますが、実際にはサブディレクトリ内のファイルは更新されません。

4

3 に答える 3

3

書き込み用にディレクトリを開きません。文字列のモード部分なしでopendirを使用するだけです:

opendir my($dir), $dirname or die "Could not open $dirname: $!";

ただし、それは必要ありません。File::Find を使用して、必要なファイルのリストを作成できます。

#!/usr/bin/perl
厳密に使用します。
警告を使用します。

File::Basename を使用します。
File::Find を使用します。
File::Find::Closures を使用 qw(find_regular_files);
File::Spec::Functions qw(catfile); を使用します。


my( $wanted, $reporter ) = find_regular_files;
find( $wanted, $ARGV[0] );


私の $prefix = 'recursive_';


foreach my $file ( $reporter->() )
    {
    my $basename = basename( $file );

    if( index( $basename, $prefix ) == 0 )
        {
        print STDERR "$file already has '$prefix'! Skipping.\n";
        次;
        }

    私の $new_path = catfile(
        ディレクトリ名( $file ),
        "recursive_$basename"
        );

    until( $file の名前を変更、$new_path )
        {
        print STDERR "$file の名前を変更できませんでした: $!\n";
        次;
        }

    print $file, "\n";  
    }
于 2009-01-02T16:47:29.830 に答える
3

これについては、おそらくFile::Findモジュールをチェックアウトする必要があります。これにより、ディレクトリ ツリーの上下の再帰がより簡単になります。

おそらく、ファイル名をスキャンし、で始まらないものを変更して、reference_そうする必要があります。そのためには、ファイル名をディレクトリ名とファイル名に分割し、ファイル名部分の前にreference_. これはFile::Basenameモジュールで行われます。

ある時点で、スクリプトを 3 回目に実行したときの動作を決定する必要があります。で始まるreference_ファイルは上書きされますか、それとも接頭辞のないファイルは上書きされますか?

ファイルの名前が変更されない理由は、名前変更操作がコメント アウトされているためです。スクリプトの先頭に追加することを忘れないでください(使用したオプションとuse strict;同様)。-w

配列内のファイルのリストを取得する場合@files(名前は基本名であるため、File::Basename をいじる必要はありません)、ループは次のようになります。

   foreach my $one (@files)
   {
        my $new = "reference_$one";
        print "$one --> $new\n";
        rename $one, $new or die "failed to rename $one to $new ($!)";
   }
于 2009-01-02T10:16:17.277 に答える
0

coreutils for Windowsfindユーティリティを使用して:

$ find -iname "*.bmp" | perl -wlne"chomp; ($prefix, $basename) = split(m~\/([^/]+)$~, $_); rename($_, join(q(/), ($prefix, q(reference_).$basename))) or warn qq(failed to rename '$_': $!)"
于 2009-01-02T11:18:07.137 に答える