두 개의 텍스트 파일의 공통 줄 (유사성)을 출력합니까 (diff의 반대)?


21

Diff는 두 파일 간의 변경 사항을 표시하는 훌륭한 도구입니다. 그러나 차이점을 무시하면서 두 텍스트 파일의 유사성을 표시하는 방법은 무엇입니까?

즉 샘플 입력 :

a:
Foo Bar
X
Hello
World
42

b:
Foo Baz
Hello
World
23

의사 출력 (이와 같은 것) :

@@ 2,3
=Hello World

이 경우 줄 정보가 손실되므로 두 파일을 정렬하고 comm을 사용하는 것만으로는 충분하지 않습니다.

답변:


24

diff를 원하지 않더라도 diff를 사용하는 것은 어떻습니까? 이 시도:

diff --unchanged-group-format='@@ %dn,%df 
  %<' --old-group-format='' --new-group-format='' \
  --changed-group-format='' a.txt b.txt

다음은 샘플 데이터로 얻은 것입니다.

$ cat a.txt 
Foo Bar
X
Hello
World
42
$ cat b.txt 
Foo Baz
Hello
World
23
$ diff --unchanged-group-format='@@ %dn,%df
%<' --old-group-format='' --new-group-format='' \
  --changed-group-format='' a.txt b.txt
@@ 2,3
Hello
World

2
다음과 같이 리터럴 개행을 포함하지 않아도됩니다....%df'$'\n''%<'...
추후 공지가있을 때까지 일시 중지되었습니다.

1
다음과 같이 할 수도 있습니다 : ... --unchanged-group-format="@@ %dn,%df%c'\012'%<" ...(큰 따옴표에 유의하십시오.)
추후 공지가있을 때까지 일시 중지되었습니다.

좋은 물건! 나는 diff 매뉴얼 페이지를 보았 기 때문에 이러한 옵션을 몰랐습니다 ...
maxschlepzig

diff --version diff (GNU diffutils) 2.8.1을 사용하고 있는데 다음과 같은 오류가 발생합니다. diff : 충돌하는 출력 스타일 옵션 diff : 자세한 내용은`diff --help '를 시도하십시오.
Sujay

diff 별칭이 정의되어 있기 때문에 "오류 : diff : 충돌하는 출력 스타일 옵션 diff"가 표시되었습니다. which diff이것이 문제인지 확인하는 데 사용 하십시오.
justinjhendrick

14
grep -Fxf file1 file2

-F정규 -x표현식과 일치 하지 않음 (정규 표현식 제외), 전체 라인 일치 만 -f의미 , 인수로 명명 된 파일에서 '패턴'(예 : 라인)을 가져옵니다.


3
인가되지 -f-F교환? 적어도 내 grep버전에서는 그런 식입니다. 와 같은 인수에 file2입력 을 제공해야하며 작동합니다. -fcat file1 | grep -Fxf file2
비 레이

이것은 나를 위해 작동하지 않습니다.
Chaminda Bandara

7

comm사용할 수 있습니다. man comm모든 옵션 comm -12 ...에 대해 두 입력에 모두 존재하는 행만 표시하는 데 사용하려고합니다 .

사람들이 지적했듯이 sort먼저 입력을 전달해야합니다 .


1
흠, 그것은 두 파일에서 같은 줄 번호에있는 공통 줄에 대해서만 작동합니다.
maxschlepzig

2
comm은 정렬 된 파일에만 해당되며 OP의 사용 사례에 유용한 출력을 제공하지는 않습니다. 그의 예 : $ comm -12 ab Hello World 통신 : 파일 1은 정렬 된 순서가 아닙니다 통신 : 파일 2는 정렬 된 순서가 아닙니다
Marcel Stimberg

@ maxschlepzig : 파일을 comm에 전달하기 전에 정렬해야합니다.
Hemant

2
정렬하면 공통 선의 위치에 대한 모든 정보가 제거됩니다. diff와 비교하기 전에 파일을 정렬하지 않습니다.
Marcel Stimberg

7

나는 당신이 원하는 것을하는 단일 명령이 있다고 생각하지 않습니다. 당신의 출력을 결합하는 시도 할 수 diff와를 grep하지만. 텍스트 파일은 문자의 아무도를 포함하지 않는 경우 |, <, >다음은 당신에게 어느 정도 유용한 출력을 제공합니다 :

$ diff --side-by-side a b | grep -n -v "[|<>]"
3:Hello                             Hello
4:World                             World

이 시도 :diff --width=155 --left-column --side-by-side a b | grep -n -v '|' | sed 's/ *($//'
추후 공지가있을 때까지 일시 중지.

그것은 더 좋아 보이지만 grep에 <와>를 포함시켜 두 파일에서 추가 된 줄을 제거해야합니다.
Marcel Stimberg 7:24에

2

Dick Grune은 이런 종류의 도구를 작성했습니다.

http://dickgrune.com/Programs/similarity_tester/

다양한 언어의 구문을 구문 분석하는 버전이 있으므로 이름이 바뀐 변수와 같은 것을 변경하지 않은 것으로 볼 수 있습니다.

similarity-tester데비안과 우분투에서와 같이 패키지됩니다 .

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