공통 줄을 표시하는 방법 (역 diff)?


170

일련의 텍스트 파일이있어서 서로 다른 줄보다는 공통 줄을 알고 싶습니다. 커맨드 라인 유닉스 나 창은 괜찮습니다.

foo :

linux-vdso.so.1 =>  (0x00007fffccffe000)
libvlc.so.2 => /usr/lib/libvlc.so.2 (0x00007f0dc4b0b000)
libvlccore.so.0 => /usr/lib/libvlccore.so.0 (0x00007f0dc483f000)
libc.so.6 => /lib/libc.so.6 (0x00007f0dc44cd000)

바:

libkdeui.so.5 => /usr/lib/libkdeui.so.5 (0x00007f716ae22000)
libkio.so.5 => /usr/lib/libkio.so.5 (0x00007f716a96d000)
linux-vdso.so.1 =>  (0x00007fffccffe000)

따라서이 두 파일 위에 원하는 유틸리티의 출력이 비슷할 것입니다 file1:line_number, file2:line_number == matching text (단지 제안하면 구문이 무엇인지 상관하지 않습니다).

foo:1, bar:3 == linux-vdso.so.1 =>  (0x00007fffccffe000)

감사.


@ChristopherSchultz 내 실수. 첫 번째 예의 첫 번째 줄은 두 번째 예의 마지막 줄과 일치한다고 가정합니다. 실수를 잡아 주셔서 감사합니다. 바꾸다.
matt wilkie

1
좋은 대답을 가진 또 다른 비슷한 질문 : unix.stackexchange.com/questions/1079/…
MortezaE

답변:


210

* nix에서는 comm 을 사용할 수 있습니다 . 질문에 대한 답변은 다음과 같습니다.

comm -1 -2 file1.sorted file2.sorted 
# where file1 and file2 are sorted and piped into *.sorted

전체 사용법은 다음과 같습니다 comm.

comm [-1] [-2] [-3 ] file1 file2
-1 Suppress the output column of lines unique to file1.
-2 Suppress the output column of lines unique to file2.
-3 Suppress the output column of lines duplicated in file1 and file2. 

또한 man 페이지에서 언급 한 것처럼 comm을 사용하기 전에 파일을 정렬하는 것이 중요합니다.


3
comm [-1] [-2] [-3] file1 file2 -1 file1에 고유 한 행의 출력 열을 억제합니다. -2 file2에 고유 한 행의 출력 열을 억제합니다. -3 file1과 file2에 중복 된 행의 출력 열을 억제합니다.
ojblass

@ojblass : 답변에 이것을 추가했습니다.
Matt J

6
comm을 사용하기 전에 파일을 정렬하는 것이 중요하다는 것을 알았습니다. 아마도 대답에 추가하십시오.
매트 윌키

11
질문에 대한 짧은 답변 : comm -1 -2 file1 file2
greggles

6
파일 정렬되지 않은 경우이 작업을 사용할 수 있습니다 : 통신을 -1 -2 <(일종의 파일 이름 1) <(일종의 filename2)
케빈 휠러

56

중복으로 나열된 질문 에서이 답변을 찾았습니다 . 나는 grep을 comm보다 관리하기 쉽기 때문에 일치하는 행 세트를 원한다면 (예 : CSV 비교에 유용) 간단히 사용하십시오.

grep -F -x -f file1 file2

또는 단순화 된 fgrep 버전

fgrep -xf file1 file2

또한 file2*두 개가 아닌 여러 파일에 공통 인 행을 찾아서 찾는 데 사용할 수 있습니다 .

다른 편리한 변형은 다음과 같습니다.

  • -n 일치하는 각 줄의 줄 번호를 표시하는 플래그
  • -c 일치하는 줄 수만 계산
  • -vfile2 에서 다른 행만 표시합니다 (또는 사용 diff).

사용 comm속도는 빠르지 만 파일 속도를 먼저 정렬해야하는 비용이 발생합니다. '역방향 diff'로는 그다지 유용하지 않습니다.


Ryder에게 감사드립니다. 이것은 많은 사람들에게 통신하는 것보다 더 유용 할 수 있습니다. 소스 답변에 링크해야합니다 (오른쪽 탐색 메뉴에는 Q에 링크 된 링크가 6 개가 넘습니다. 찾는 약간의 작업입니다). grep이 정렬되지 않은 또는 다르게 정렬 된 입력에서 얼마나 잘 수행되는지 알고 각 행 번호의 일치를 인쇄 할 수도 있습니다.
matt wilkie

1
@ mattwilkie 나는 다시 돌아와서 -v깃발을 쓰다듬고 나서 깃발 의 사용을 분명히해야한다고 느꼈습니다 . 두 개의 CSV 파일 file1과 file2가 있고 겹치는 행과 겹치지 않는 행이 모두 있다고 가정 해보십시오. 겹치지 않는 행을 모두 원한다면을 사용 fgrep -v file1 file2하면 file2의 겹치지 않는 행만 반환하고 file1의 겹치지 않는 추가 행은 반환 하지 않습니다 . 이것은 일부에게는 명백 할 수 있지만, 위험보다 오해보다 명백한 것을 진술하는 것이 좋습니다. 이 경우 파일을 정렬하고 사용하는 comm것이 여전히 더 나은 선택입니다.
라이더

1
돌아와 라이더를 명확히 해주셔서 감사합니다. 특별한주의를 기울이고 높이 평가합니다 (오래된 것들이 사라지기 쉽도록!). 개인적으로 정렬이 원치 않는 오버 헤드 일 때 여전히 사용하지만 통신은 분명히 커뮤니티의 선택이기 때문에 허용 된 답변을 전환했습니다.
matt wilkie

2
사용시 또 다른 문제 grep: 첫 번째 파일의 빈 줄은 두 번째 파일의 모든 줄과 일치합니다. file1빈 줄이 없는지 확인하십시오 . 그렇지 않으면 파일이 동일한 것처럼 보입니다.
Christopher Schultz

grep -Fxf그것은 나를위한 것입니다.
loxaxs

35

이전에 여기에 물었습니다 : 두 파일에서 공통적 인 줄을 찾는 유닉스 명령

펄로 시도해 볼 수도 있습니다 (신용 은 여기로갑니다 )

perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/'  file1 file2

1
감사. Perl one liner가 크로스 플랫폼이므로 두 가지 답변을 모두 수락하고 싶습니다. Comm은 더 단순하기 때문에 끄덕입니다.
매트 윌키

1
완전한. Windows에서 cygwin 터미널을 사용하여 comm쉽게 사용할 수 없었습니다. 이것은 완벽한 대안이었습니다.
Qix-MONICA가 MISTREATED

3
이것은 라인이 어떻게 정렬되는지에 대해서는 신경 쓰지 않습니다. 통신보다 정확합니다.
enl8enmentnow

1
설명이 여기에 있습니다 : stackoverflow.com/questions/17552789/...
크리스 Koknat

17

방금이 스레드에서 comm 명령을 배웠지 만 추가 항목을 추가하고 싶었습니다. 파일이 정렬되지 않고 원본 파일을 건드리지 않으려는 경우 sort 명령의 출력을 파이프 할 수 있습니다. 원본 파일은 그대로 유지됩니다. bash에서 작동하지만 다른 쉘에 대해서는 말할 수 없습니다.

comm -1 -2 <(sort file1) <(sort file2)

파일 대신 명령 출력을 비교하도록 확장 할 수 있습니다.

comm -1 -2 <(ls /dir1 | sort) <(ls /dir2 | sort)

9

가장 쉬운 방법은 다음과 같습니다.

awk 'NR==FNR{a[$1]++;next} a[$1] ' file1 file2

파일을 정렬 할 필요는 없습니다.


1
이것은 소스 템플릿을 재구성 할 수 있다는 점에서 대부분의 답변과 다릅니다. 동일한 래퍼로 작성된 두 개의 파일이 있으며 몇 가지 지점에 다른 텍스트가 삽입되었습니다. 이 답변을 통해 래퍼를 복구 할 수있었습니다.
Lucas Gonze

1

정보를 얻기 위해 Windows 용 "grep -F -x -f file1 file2"와 동일한 작업을 수행하는 작은 도구를 만들었습니다 (Windows 에서이 명령과 동등한 것을 찾지 못 했으므로)

여기 있습니다 : http://www.nerdzcore.com/?page=commonlines

사용법은 "CommonLines inputFile1 inputFile2 outputFile"입니다.

소스 코드도 사용 가능 (GPL)


1

Windows 에서는 CompareObject 와 함께 Powershell 스크립트를 사용할 수 있습니다

compare-object -IncludeEqual -ExcludeDifferent -PassThru (get-content A.txt) (get-content B.txt)> MATCHING.txt | Out-Null #Find Matching Lines

비교 대상 :

  • -ExcludeDifferent없이 IncludeEqual : 모두
  • -InclueEqual이없는 ​​다른 제외 : 없음
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.