파일 헤드 차이


11

두 개의 파일이 있습니다. 한 파일은 다른 파일의 하위 집합이라고 생각합니다. 첫 번째 파일에서 두 번째 파일이 맞는 위치를 간결하게 식별하기 위해 파일을 비교하는 방법이 있습니까?



한 파일의 행이 다른 파일의 하위 시퀀스이거나 실제로 연속적인 하위 문자열임을 의미합니까?
Kaz

연속 부분 문자열 @Kaz.
Richard

답변:


14

diff -e bigger smaller 출력이 "유효한 스크립트"이므로 트릭을 수행하지만 약간의 해석이 필요합니다.

"더 큰"과 "더 작은"이라는 두 개의 파일을 만들었는데, "더 작은"의 내용이 "diff -e 더 큰 더 작은"을 수행하는 "더 큰"의 5 ~ 9 행과 동일합니다.

% diff -e bigger smaller
10,15d
1,4d

즉, " '더 큰'의 10 ~ 15 행을 삭제 한 다음 '작은'을 얻기 위해 1 ~ 4 행을 삭제하십시오." 즉, "더 작은"은 "더 큰"의 5-9 행입니다.

파일 이름을 바꾸면 뭔가 더 복잡해졌습니다. "smaller"가 실제로 "bigger"의 하위 세트를 구성하는 경우 'd'(삭제 용) 명령 만 출력에 표시됩니다.


5

meld를 사용 하여 시각적으로 수행 할 수 있습니다 . 불행히도 GUI 도구이지만 한 번만 수행하고 비교적 작은 파일에서 수행하려면 괜찮습니다.

아래 이미지는 다음의 출력입니다 meld a b.

여기에 이미지 설명을 입력하십시오


1
Meld는 훌륭하지만 100MB 이상의 파일에서는 잘 작동하지 않습니다.
Richard

@Richard는 그렇지 않습니다. 어쨌든 커맨드 라인 도구를 선호합니다.
terdon

vimdiff터미널에서 사용할 수있는 것처럼 보입니다 .
Patrick

2

파일이 충분히 작 으면 Perl에 파일을 넣고 정규식 엔진이 트릭을 수행하도록 할 수 있습니다.

perl -0777e '
        open "$FILE1","<","file_1";
        open "$FILE2","<","file_2";
        $file_1 = <$FILE1>;
        $file_2 = <$FILE2>;
        print "file_2 is", $file_1 =~ /\Q$file_2\E/ ? "" : "not";
        print " a subset of file_1\n";
'

-0777스위치는 Perl에게 입력 레코드 구분 기호 $/를 정의되지 않은 값으로 설정하여 파일을 완전히 처리하도록 지시 합니다.


1
무엇을 777합니까? NULL을 전달 $/하지만 왜 그럴까요? 또한 이것들은 좀 난해한 스위치이기 때문에 비 펄 사람들에게는 설명이 좋을 것입니다.
terdon

1
@ terdon 실제로 파일 전체를 문지르 기 위해하고 있습니다. 설명이 추가되었습니다.
Joseph R.

그러나 왜 이것이 필요한가? $a=<$fh>어쨌든 맞아야합니까?
terdon

1
@terdon 내가 아는 바가 없다. 파일의 한 줄만 열리 도록 기본적 $/으로 설정 되어 있습니다. 물론 명령 줄 동작에 내가 모르는 다른 기본값이없는 한? \n$a=<$fh>$fhperl
Joseph R.

아아, 예, 내 나쁜, 나는 거의 파일을 훔치거나 while $foo=<FILE>관용구를 사용 하지 않으므로 확실하지 않고 작동하는 것처럼 보이는 (잘못된) 테스트를 실행했습니다. 신경 쓰지 마 :).
terdon

1

파일이 텍스트 파일이고 라인의 시작 부분 smaller에서 bigger시작하면 awk다음 과 같이 구현하기가 어렵지 않습니다 .

awk -v i=0 'NR==FNR{l[n++]=$0;next}
    {if ($0 == l[i]) {if (++i == n) {print FNR-n+1;exit}} else i=0}
    ' smaller bigger

1

귀하의 질문은 "파일의 차이점"입니다. 하나의 파일이 다른 파일의 헤드라는 것을 의미한다면, 간단한 cmp것이 다음과 같이 알려줄 것입니다.

cmp big_file small_file
cmp: EOF on small_file

그것은 읽는 동안 파일 끝에 도달 할 때까지 두 파일의 차이가 감지되지 않았 음을 나타 small_file냅니다.

그러나 작은 파일의 전체 텍스트가 내부 어디에서나 발생할 수 있다는 것을 의미한다면 big_file메모리에 두 파일을 모두 넣을 수 있다고 가정하면

perl -le '
   use autodie;
   undef $/;
   open SMALL, "<", "small_file";
   open BIG, "<", "big_file";
   $small = <SMALL>;
   $big = <BIG>;
   $pos = index $big, $small;
   print $pos if $pos >= 0;
'

그러면 big_file내용이 small_file있는 위치 내 오프셋이 인쇄됩니다 (예 : small_file시작 부분에서 일치하는 경우 0 big_file). 경우 small_file내부 일치하지 않는 big_file, 아무 것도 인쇄되지 않습니다. 오류가 있으면 종료 상태는 0이 아닙니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.