ディレクトリの下のすべてのファイル名にプレフィックスを追加するにはどうすればよいですか?
-
03-07-2019 - |
質問
すべてのディレクトリおよびサブディレクトリ内のすべての* .bmpファイルの名前に文字列(reference_
)を接頭辞として付けようとしています。 Silkスクリプトを初めて実行すると、ディレクトリとサブディレクトリが作成され、各サブディレクトリの下に、各モバイルアプリケーションのスクリーンショットが.bmp
拡張子で保存されます。
自動シルクスクリプトを2回実行すると、すべてのサブディレクトリに* .bmpファイルが再度作成されます。スクリプトを2回実行する前に、すべての* .bmpの前に文字列first_screen.bmp
。
たとえば、reference_first_screen.bmp
から<=>、
私は以下のようなディレクトリ構造を持っています:
C:\Image_Repository\BG_Images\second
...
C:\Image_Repository\BG_Images\sixth
<=>および<=>ファイルなどを持っている...
誰か助けてもらえますか?
すべての画像ファイル名の前に<=>文字列を付けるにはどうすればよいですか?
スクリプトを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;
}
「+ <!> lt;」でオープンコールを試みましたモードですが、読み取りおよび書き込みモードでコンパイルエラーが発生します。 このコードを実行すると、BG_imagesフォルダー内のファイルに接頭辞付きの文字列が表示されますが、実際にはサブディレクトリ内のファイルは更新されません。
解決
書き込み用のディレクトリを開きません。文字列のモード部分なしで opendir を使用するだけです:
opendir my($dir), $dirname or die "Could not open $dirname: $!";
ただし、その必要はありません。 File :: Findを使用して、必要なファイルのリストを作成できます。
#!/usr/bin/perl use strict; use warnings; use File::Basename; use File::Find; use File::Find::Closures qw(find_regular_files); use File::Spec::Functions qw(catfile); my( $wanted, $reporter ) = find_regular_files; find( $wanted, $ARGV[0] ); my $prefix = 'recursive_'; foreach my $file ( $reporter->() ) { my $basename = basename( $file ); if( index( $basename, $prefix ) == 0 ) { print STDERR "$file already has '$prefix'! Skipping.\n"; next; } my $new_path = catfile( dirname( $file ), "recursive_$basename" ); unless( rename $file, $new_path ) { print STDERR "Could not rename $file: $!\n"; next; } print $file, "\n"; }
他のヒント
おそらく File :: Find モジュールをチェックしてください-それディレクトリツリーの上下の再帰が簡単になります。
ファイル名をスキャンし、reference_
で始まらないファイル名を変更するようにします。そのためには、ファイル名をディレクトリ名とファイル名に分割し、ファイル名部分の前にuse strict;
を付ける必要があります。これは、 File :: Basename モジュールで行いました。
ある時点で、スクリプトを3回目に実行したときに何が起こるかを決定する必要があります。すでに-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 ($!)";
}
coreutils for Windows のfind
ユーティリティを使用して:
$ find -iname "*.bmp" | perl -wlne"chomp; ($prefix, $basename) = split(m~\/([^/]+)$~, $_); rename($_, join(q(/), ($prefix, q(reference_).$basename))) or warn qq(failed to rename '$_': $!)"