2010-05-17 4 views
13

이 질문은 코드에 대한 변경 사항이 텍스트 파일에 출력하는 값에 영향을 미치지 않도록해야합니다. 이상적으로, 나는 서브 파일을 두 개의 파일 이름을 취하고 내용이 동일한지 아닌지 공백 여부에 따라 return 1 또는 return 0을 사용합니다.Perl을 사용하여 두 파일의 내용이 동일한 지 어떻게 판단 할 수 있습니까?

텍스트 처리가 Perl의 forté라는 점을 감안할 때 두 파일을 비교하고 그 파일이 동일한지 아닌지 (테스트되지 않은 코드) 여부를 쉽게 판단 할 수 있어야합니다. 나는 (SAN을 CPAN 모듈) 생각할 수

use strict; 
use warnings; 

sub files_match { 

    my ($fileA, $fileB) = @_; 
    open my $file1, '<', $fileA; 
    open my $file2, '<', $fileB; 

    while (my $lineA = <$file1>) { 

     next if $lineA eq <$file2>; 
     return 0 and last; 
    } 

    return 1; 
} 

있는 유일한 방법은 문제의 두 파일을 열고 차이가 발견 될 때까지 한 줄 한 줄을 읽는 것입니다. 차이가 없으면 파일은 동일해야합니다.

그러나이 방법은 제한적이며 서투른 있습니다. 두 파일의 총 행 수가 다른 경우 어떻게해야합니까? 행 수를 결정하기 위해 열고 닫아야할까요? 텍스트를 스캔하기 위해 다시 열어야합니까? 왝.

이와 관련하여 perlfaq5에 아무것도 표시되지 않습니다. 핵심 Perl 5.6.1 배포판을 제외하고는 모듈에서 벗어나고 싶습니다.

+0

나는이 질문이 전에는 나오지 않았다는 것에 놀랐습니다. – Zaid

+1

왜 diff를 사용하지 않습니까? - 당신이 * nix – heferav

+0

@heferav에있는 경우 : Perl에 렌더링하여 제대로 처리 할 수 ​​있습니다. 나는 유닉스 프로그래밍에서 그다지 많은 것을하지 못했다.) – Zaid

답변

28

core에 있습니다.

use File::Compare; 

if (compare("file1", "file2") == 0) { 
    print "They're equal\n"; 
} 
+0

휴! 나는 그것이 단순 할 것이라고 알고있었습니다. – Zaid

+0

'File :: Compare'는 파일을 열고 한 줄씩 읽는 것과 거의 같습니다 (또는 세 번째 인수를 사용하는 경우 블록 단위로 읽음). 퍼포먼스에 대해 걱정이된다면 파일 크기와 inode 번호를 호출하기 전에 체크 할 수 있습니다. –

+0

사실 File :: Compare는 이미 파일 크기를 확인합니다. http://cpan.uwinnipeg.ca/htdocs/perl/File/Compare.pm.html –

7

파일이 다른지 먼저 확인할 수있는 몇 가지 O (1) 검사가 있습니다.

파일의 크기가 다른 경우에는 분명히 다릅니다. stat 함수는 파일의 크기를 반환합니다. 또한 유용한 또 다른 데이터 인 inode 번호를 반환합니다. 두 파일이 실제로 같은 파일 인 경우 (두 파일 모두에 동일한 파일 이름이 전달되었거나 두 파일 모두 같은 파일에 대한 하드 링크이기 때문에) inode 번호는 동일합니다. 파일 자체는 분명히 동일합니다. 이 두 가지 검사를 실행하면 두 개의 로컬 파일을 서로 직접 비교하는 것 이외에 동등성을 비교하는 더 좋은 방법이 없습니다. 물론 줄 단위로 처리 할 필요가 없습니다. 원하는 경우 큰 블록으로 읽을 수 있습니다.

#!/usr/bin/perl 

use strict; 
use warnings; 

use File::Compare(); 

sub compare { 
    my ($first, $second)    = @_; 
    my ($first_inode, $first_size) = (stat $first)[1, 7]; 
    my ($second_inode, $second_size) = (stat $second)[1, 7]; 

    #same file, so must be the same; 
    return 0 if $first_inode == $second_inode; 

    #different sizes, so must be different 
    return 1 unless $first_size == $second_size; 

    return File::Compare::compare @_; 
} 

print compare(@ARGV) ? "not the " : "", "same\n"; 
+0

소스를 확인하십시오.이 질문은 이식 가능한 스크립팅 언어 (Perl)의 문맥에 있습니다. 이 대답은 OS 및 파일 시스템과 관련된 것입니다. inode가 독특하고 비교 가능한 Windows (모든 파일 시스템)에서 특히 실패 할 것이라는 가정과 UNIX의 블록 지향 파일 시스템에서도 다른 볼륨, 파티션, 서브 볼륨 등에서 inode에 대해 실패합니다. – Garen

관련 문제