디렉토리 아래의 모든 파일 이름에 접두사를 추가하려면 어떻게해야합니까?

StackOverflow https://stackoverflow.com/questions/406396

  •  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 '$_': $!)"
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top