디렉토리 아래의 모든 파일 이름에 접두사를 추가하려면 어떻게해야합니까?
-
03-07-2019 - |
문제
나는 문자열을 접두사하려고한다.reference_
) 모든 디렉토리와 하위 디렉토리의 모든 *.BMP 파일의 이름에. 실크 스크립트를 처음 실행하면 디렉토리와 하위 디렉토리를 생성하며 각 하위 디렉토리 아래에서 각 모바일 애플리케이션의 SCEENSHOT를 저장합니다. .bmp
확대.
자동화 된 실크 스크립트를 두 번째로 실행하면 모든 하위 디렉터에서 *.BMP 파일을 다시 생성합니다. 두 번째로 스크립트를 실행하기 전에 문자열로 모든 *.bmp를 접두사하고 싶습니다. reference_
.
예를 들어 first_screen.bmp
에게 reference_first_screen.bmp
, 나는 다음과 같이 디렉토리 구조를 가지고있다.
C:\Image_Repository\BG_Images\second
...
C:\Image_Repository\BG_Images\sixth
was first_screen.bmp
그리고 first_screen.bmp
파일 등 ...
아무도 나를 도울 수 있습니까?
모든 이미지 파일 이름을 reference_
끈?
스크립트를 두 번째로 실행하면 Silk의 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 폴더에 접두사가있는 문자열로 표시되지만 실제로는 하위 디렉터에서 파일을 업데이트하지 않습니다.
해결책
당신은 글쓰기 디렉토리를 열지 않습니다. 그냥 사용하십시오 Opendir 문자열의 모드 부분없이 :
opendir my($dir), $dirname or die "Could not open $dirname: $!";
그러나 당신은 그것을 필요로하지 않습니다. 파일 :: 필요한 파일 목록을 찾으려면 찾을 수 있습니다.
#!/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"; }
다른 팁
당신은 아마도 확인해야합니다 파일 :: 찾기 이를위한 모듈 - 디렉토리 트리를 더 이상 위아래로 볼 수 있습니다.
파일 이름을 스캔하고 시작하지 않은 이름을 수정해야합니다. reference_
그들이 할 수 있도록. 파일 이름을 디렉토리 이름과 파일 이름으로 분할 한 다음 파일 이름 부분을 다음 reference_
. 그것은 끝났습니다 파일 ::베이스 이름 기준 치수.
어느 시점에서 스크립트를 세 번째로 실행할 때 어떤 일이 발생하는지 결정해야합니다. 이미 시작한 파일을 수행하십시오 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 ($!)";
}
의 도움으로 find
유틸리티 Windows 용 Coreutil:
$ find -iname "*.bmp" | perl -wlne"chomp; ($prefix, $basename) = split(m~\/([^/]+)$~, $_); rename($_, join(q(/), ($prefix, q(reference_).$basename))) or warn qq(failed to rename '$_': $!)"