2014-12-15 3 views
1

프로젝트 디렉토리 구조와 소스 파일을 주로 볼 수있는 스크립트를 개발하려고합니다. 파일 이름에 대개 Java 및 XML 파일이 잘못된 경우 일 수 있습니다. 파일이 위치한 디렉토리/드라이브에 이름이 지정되는 코드. 예 : 드라이브의 코드 Abc.xml에있는 ABC.xml 이 문제는 Windows에서 Linux로 마이그레이션 할 때 발견되었습니다.perl 스크립트가 대소 문자를 구분하는 자바 소스 코드를 검색합니다.

원래 ACK를 사용한다고 생각했지만 여기서 방화벽은 CPAN을 차단하는 것처럼 보였으므로 dmake를 사용하여 내 컴퓨터에 수동으로 설치하지 못했습니다. (최신 버전의 딸기 사용)

여기까지 내가 지금까지 함께 해왔 던 것입니다. 재귀 적으로 자바와 XML 파일을 가져 오는 기본 경로 아래의 각 하위 디렉토리를 검색합니다. 그런 다음 발견 된 각 파일을 열고 sourcelist의 각 이름에 대해 대소 문자를 구분하지 않고 검색을 수행 한 다음 검색 결과에서 대소 문자를 구분하여 일치하는 결과를 제거한 다음 부정적인 결과를 해시로 저장합니다. 대/소문자가 파일 이름과 일치하지 않는 각 파일의 이름을 저장하는 배열 (값)이있는 각 소스 파일 (키). 마지막에는 해시를 출력 할 계획입니다.

현재 배열의 해시를 설정하는 데 어려움을 겪고있는 임 이겠지만 대체/더 간단한 솔루션을 사용할 수 있습니다.

my $source = "C:/sampleSourcefiles"; 
my $base_path = "C:/baseDIRprojectCode"; 
my @searchList; 
my %report; 

#open source file directory. 
if($source){ 
    opendir (DIR, $source) or die "Directory not found \n" ; 
    @searchList = grep(/^.+\..+$/, readdir(DIR)); 
    closedir DIR; 
} 

#code does not have file extensions trim from names 
foreach my $file (@searchList){ 
    $file =~ s/\.dat|xml$//; 
    #print "$file\n"; 
} 


process_files ($base_path); 

# Accepts one argument: the full path to a directory. 
sub process_files { 
    my $path = shift; 

    # Open the directory. 
    opendir (DIR, $path) or die "Unable to open $path: $!"; 

    # Read in the files. 
    my @files = grep {!/^\./} readdir (DIR); 
    closedir (DIR); 

    # append the full path to the file names. 
    @files = map { $path . '/' . $_ } @files; 

    for (@files) { 

     # If the file is a directory 
     if (-d $_) { 
      process_files ($_); 

     # If it isn't a directory, process the file. 
     } else { 
      file_search($_); 
     } 
    } 
} 

# Accepts one argument: the source file to search 
sub file_search { 
    my $file = shift; 

    #ignore all files not java or xml 
    if ($file =~ /\.xml|java$/){ 

     #search for match to any file in the list 
     foreach my $item (@searchList){ 
      open(F, $file); 
      my @lines = <F>; 
      close F; 
      my @result = grep /$item/i , @lines; 

      if (@result){ 
       %report($item, @result); 

       #foreach my $res (@result){ 
       # if($res eq $file){ 
       #  print "good result\n"; 
       # } else { 
       #  print "Inequality match found in file $file for $res\n"; 
       # } 
       #} 
      } else { 
       } 
     } 
    } 
} 

답변

0

잘하고 있지만 개선 할 수 있습니다. 모든

첫째 줄

%report($item, @result); 

어떤 이해가되지 않습니다; 서브 루틴 호출 만해서는 안됩니까?

report($item, @result); 

둘째, 무엇을 해시를 사용 하시겠습니까?

셋째 : 매우 효율적으로 반복하지 않습니다. 각 파일 이름에 대해 파일을 다시 열고 다시 읽는 이유는 무엇입니까?

IT는 qr를 사용하여 다음 중 어떤 경우 소문자를 구별 검색 하나의 큰 정규 표현식을 구축, 첫번째 파일의 목록을 원래의 형태

my %lower2original = map { (lc($_), $_) } @files; 

자신의 소문자 양식을지도하는 것이 더 효율적입니다 운영자 : 다음

my $regex = '\b(' . join('|', @files), ')\b'; 
$regex = qr/$regex/ip; 

차례로 각 파일을 열고 스캔 같은이

while (my ($match) = /$regex/g) 
{ 
    my $original = $lower2original{lc($match)}; 
    if ($match ne $original) 
    { 
     print "case mismatch: line $. of $file has $match instead of $original\n"; 
    } 
} 
를 사용을 통해

넷째 : use File::Find::Rule to obtain the list of files입니다.

+0

나는 찾고자하는 이름의 해시에 결과의 내용을 추가하는 것으로 그 선을 돌리고 자했다. 하지만 나는 문제를 다루는 메모리를 실행할 것이라고 확신했다. – pearler

+0

'while (my ($ match) =/$ regex/g)'이 절대로 true로 전달되지 않는 것처럼 보입니다. 내 추측은 그 정규식이 올바르지 않다는 것입니다 내가 모디파이어 피가 뭔지 모르지만 위의 것을 따랐습니다? $ regex = qr/$ regex/ip; 뒤에있는 정규식은 다음과 같습니다. (?^pi : \ b (FileA | FILEB) \ b) – pearler

+0

코드를 시험하지 않았습니다. 나는 당신이 [p] (http://perldoc.perl.org/perlop.html#qr/STRING/msixpodual)을 필요로하는지조차 모른다. 'qr' 호출에'g'를 추가해야 할 수도 있습니다. 따라서 세부 사항 중 일부는 잘못되었을 수 있지만 그 방법은 효과가 있습니다. – reinierpost

관련 문제