2014-05-21 4 views
3

참고 : 관련 질문은 더 이상 사용되지 않는 모듈을 사용하여 해결되며 OS마다 일관되지 않습니다. 현재 질문에 대한 대답은 새로운 모듈을 사용하므로 여기에 게시됩니다.Perl은 특정 형식의 파일을 반복적으로 복사합니다.

파일을 재귀 적으로 복사 할 때 File::NCopy CPAN 모듈을 사용하는 모듈이 있습니다.

문제는 - 대상으로 특정 파일 형식의 파일 만 재귀 적으로 복사해야합니다. 어떤 방법으로 원본을 확장명으로 필터링 할 수 있습니까?

다른 방법으로 숨겨진 파일을 제외한 모든 파일을 복사하는 방법이 있습니까? 내 주요 문제는 .git 폴더도 복사됩니다 - 어떤 바람직하지 않습니다.

플랫폼 : 맥 OS

대안 탐구는 :

1) 파일 :: 복사 : : 재귀 모듈 : - 파일이나 디렉토리의 재귀 사본을 제공 할 것으로 보인다. 숨김 파일 또는 필터 제외에 도움이되지 않는 것 같습니다. 2) rsync -avz --exclude = ". *"를 사용하면 재귀 복사 기능과 결합 할 수 없습니다.

3) 자국 해결 방안은 How can I copy a directory recursively and filter filenames in Perl?과 비슷합니다. - 최후의 수단 일 수도 있지만, 다른 플랫폼에서 조정 및 테스트하지 않으면 휴대용이 아닌 것 같습니다. 모듈이 이미 존재하지 않는 한 이것으로 돌아갈 것입니다.

4) https://metacpan.org/pod/Path::Class::Dir : - 그럴듯한 것 같습니다. - 이것을 사용하여 빠른 구현을 실행합니다.

구현 솔루션 :

내가 재귀 모듈 경로 :: 클래스 :: 디렉터리

dir($sourceDir)->recurse(callback => sub { 
    my $file = shift; 

    return if($file eq '.' || $file eq '..'); 

    return if -d $file; 

    if (<custom filter>) 
    { 
     my $path = file($file)->relative($sourceDir); 
     fcopy("$sourceDir/$path", "$destinationDir/$path") or die "Could not perform fcopy: $!"; 
    } 
}); 

상대 경로없이 사용 - 대상 폴더 구조는 동일 될 것 같지 않습니다 원본 폴더 구조로.

+2

마이너 참고 : ['File :: NCopy'] (https://metacpan.org/pod/File::NCopy)는이 파일이 더 이상 사용되지 않는다고보고하고 ['File :: Copy :: Recursive']를 사용하여 제안합니다 대신 https://metacpan.org/pod/File::Copy::Recursive). – Miller

+0

어떤 운영 체제입니까? – ooga

+0

도트 파일 AFAIK를 제외하려면 자체 개발 솔루션을 만들어야 할 수도 있습니다. – squiguy

답변

1

가장 쉬운 방법은 File::Copy::Recursive을 사용하여 디렉터리 구조를 완전히 복사 한 다음 File::Find::Rule으로 돌아가서 필터링 할 모든 디렉터리를 결정한 다음 제거하는 것입니다.

.git 폴더에 많은 양의 데이터가 저장되어 있다고 가정하면 필자가 필요로하는 것보다 많은 파일을 복사 할 때 성능이 저하 될 것으로 생각됩니다. 다음은 당신이 원하는 것을 달성하기에 충분 것이다 : 또는

use strict; 
use warnings; 

use File::Copy::Recursive qw(dircopy pathrmdir); 
use File::Find::Rule; 

my $src = '...src...'; 
my $dest = '...dest...'; 

dircopy($src, $dest) or die "Can't dircopy: $!"; 

my @git = File::Find::Rule->directory() 
          ->name('.git') 
          ->in($dest); 

pathrmdir($_) or die "Can't remove $_: $!" for (@git); 

, 당신은 자신의 롤하려는 경우, 당신은 "CVS 디렉토리를 무시"하는 방법에 대한 예제를 포함 File::Find::Rule #Further Examples 한 번 봐 걸릴 수 있습니다.

관련 문제