diff가 추가 및 삭제 된 행만 표시하도록하려면 어떻게해야합니까? diff가 할 수 없다면 어떤 도구를 사용할 수 있습니까?


69

diff가 추가 및 삭제 된 행만 표시하도록하려면 어떻게해야합니까? diff가 할 수 없다면 어떤 도구를 사용할 수 있습니까?


2
추가 및 삭제의 의미를 더 잘 정의해야합니다. 구체적으로 줄을 바꿀 수 있습니까? 그렇다면 변경된 줄을 어떻게 처리 하시겠습니까? 라인 지향 검사를 엄격하게 수행하는 경우 라인 변경은 기존 라인이 제거되고 새 라인이 추가되는 것과 동일합니다. 예를 들어, 2 개로 분할 된 라인을 어떻게 처리해야합니까? 2 개의 1 줄이 바뀌 었습니까? 2 줄이 바뀌 었나요? 한 줄이 제거되고 두 줄이 추가 되었습니까? 행이 변경되지 않는다고 보장 할 수 없다면 추가 및 삭제 만하면 더 나은 정의없이 실패 할 수 있습니다.
Christopher Cashell

나는 그 질문이 분명하지 않다고 생각한다. 그러나이 질문에 대한 적어도 하나의 해석은 다음과 같이 대답 될 수 있습니다.diff A B | grep '^[<>]'
kasperd

찾고있을 수 있습니다 comm.
Jenny D

@ChristopherCashell은 정렬 순서를 무시한다는 의미입니다. 일반적으로 일반적인 문제입니다. 일반적으로 일반적인 diff를 수행하기 전에 각면의 세그먼트 (선)를 먼저 정렬하면됩니다.
Pacerier

@Pacerier, 확실합니까? 아니면 추측하고 있습니까? 정렬 또는 검색 순서에 대한 내용은 질문에서 언급되거나 암시되지 않습니다. 이 질문은 분명하지 않으며 여러 가지 다른 방식으로 해석 될 수 있습니다. 그가 무엇을 요구 하는지 확실 하지 않으면 서 , 우리는 가정을하고 실제 문제를 해결할 수도 있고 그렇지 않을 수도있는 솔루션을 제공하고 있습니다. 또한 답변 중 하나에 대한 원래 포스터의 의견은 이것이 정렬과 관련 이 없음 을 나타냅니다. "추가 및 삭제"와 "변경"의 의미와 관련이 있습니다.
Christopher Cashell

답변:


82

통신을 시도

그것을 보는 또 다른 방법 :

  • 파일 a에만 존재하는 행을 표시합니다 (예 : a에서 삭제 된 행).

    comm -23 a b
    
  • 파일 b에만 존재하는 줄 표시 : (즉 b에 추가 된 내용)

    comm -13 a b
    
  • 한 파일 또는 다른 파일에만 존재하는 줄 표시 : (둘다는 아님)

    comm -3 a b | sed 's/^\t//'
    

(경고 : 파일 a에 TAB으로 시작하는 줄이 있으면 출력에서 첫 번째 TAB이 제거됩니다.)

정렬 된 파일 만

참고 :comm 제대로 작동하려면 두 파일을 모두 정렬해야합니다 . 정렬되지 않은 경우 정렬해야합니다.

sort <a >a.sorted
sort <b >b.sorted
comm -12 a.sorted b.sorted

파일이 너무 길면 추가 사본이 필요하므로 디스크 공간이 두 배나 필요하기 때문에 상당한 부담이 될 수 있습니다.


5
이 솔루션이 올바른 결과를 얻으려면 두 파일을 모두 정렬 (대소 문자 구분)해야한다고 추가하고 싶었습니다
marmor

1
현대의 충분한 껍질에서 다음과 같이 정렬 할 수 있습니다.comm -12 <(sort a) <(sort b)
Joshua Huber

14

comm당신이 원하는 것을 할 수 있습니다. 매뉴얼 페이지에서 :

기술

정렬 된 파일 FILE1과 FILE2를 한 줄씩 비교하십시오.

옵션이 없으면 3 열 출력을 생성합니다. 열 1에는 FILE1에 고유 한 행이 있고 열 2에는 FILE2에 고유 한 행이 있고 열 3에는 두 파일에 공통 인 행이 있습니다.

이러한 열은과 suppressable 있습니다 -1, -2그리고 -3각각.

예:

[root@dev ~]# cat a
common
shared
unique

[root@dev ~]# cat b
common
individual
shared

[root@dev ~]# comm -3 a b
    individual
unique

그리고 고유 한 줄을 원하고 어떤 파일에 있는지 신경 쓰지 않으면 :

[root@dev ~]# comm -3 a b | sed 's/^\t//'
individual
unique

매뉴얼 페이지에서 알 수 있듯이 파일을 미리 정렬해야합니다.


9

문맥, 줄 번호, +,-, <,>없이 추가 및 삭제를 표시하려면! 등, 당신은 다음과 같이 diff를 사용할 수 있습니다 :

diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt 

예를 들어, 두 개의 파일이 주어지면 :

a.txt

Common
Common
A-ONLY
Common

b.txt

Common
B-ONLY
Common
Common

다음 명령은 a에서 제거되었거나 b에 추가 된 행을 보여줍니다.

diff --changed-group-format='%<%>' --unchanged-group-format='' a.txt b.txt 

산출:

B-ONLY
A-ONLY

이 약간 다른 명령은 a.txt에서 제거 된 행을 표시합니다.

diff --changed-group-format='%<' --unchanged-group-format='' a.txt b.txt 

산출:

A-ONLY

마지막으로이 명령은 a.txt에 추가 된 줄을 보여줍니다.

diff --changed-group-format='%>' --unchanged-group-format='' a.txt b.txt 

산출

B-ONLY

2

이것이 기본적으로 diff의 기능입니다. 공백을 무시하려면 플래그를 추가해야합니까?

diff -b -B

빈 줄과 다른 수의 공백을 무시해야합니다.


1
아니요, CHANGED 줄도 표시됩니다 (문자 또는 4 개의 다른 줄). 왼쪽이나 오른쪽에만 존재하는 줄을 원합니다.
C. Ross

2
CHANGED 파일의 서로 다른 버전이 각각 왼쪽이나 오른쪽에만 존재한다고 주장 할 수 있습니다.
markdrayton

2
diff (또는 다른 도구)가 변경 사항과 삭제 된 줄을 새 줄로 바꾸는 것을 안정적으로 말할 수있는 방법이 없습니다.
Cian

1
기술적으로 diff는 원래 행이 삭제되고 새 행이 추가 된 것처럼 "변경된"행을 처리하므로 기술적으로 추가 및 삭제 된 행만 표시합니다.
KFro September

2

아니요, diff실제로 두 파일의 차이점을 생각하지는 않습니다. patch한 파일을 다른 파일로 변경하는 데 사용 하는 도구에 대한 일련의 편집 명령을 생성합니다 .

찾고있는 것을하기위한 시도의 어려움은 변경된 줄과 추가 된 줄을 변경 한 줄을 구성하는 방법을 정의하는 것입니다. 또한 행이 서로 추가, 삭제 및 변경 될 때 수행 할 작업.


내 생각과 일치 해. 원본을 수정하는 대신 새로운 것을 고려하기 위해 한 줄에서 몇 퍼센트의 문자를 변경해야합니까? 기술적으로 하나의 공통 문자가 있더라도 삭제 및 삽입 대신 "변경"으로 간주 할 수 있습니다.
Kamil Kisiel

1
diff소스를 살펴본 이후 오랜 시간 이 지났지 만 두 파일이 일치하는 위치를 추적하기 위해 모든 방식의 gyration을 기억하는 것 같습니다. 라인입니다. 그러나 (선택적으로) 축소 된 공백 또는 대소 문자를 제외하고는 인트라 라인 일치를 기억하지 못합니다. 또는 (아마도) 그 말에 영향을 미칩니다. 어쨌든, 그것은 모든 것에 관한 patch것이며 "vgrep"은 타고 나옵니다. 아마도. 화요일에.
Dennis Williamson

2

시각적 비교 도구는 두 줄의 파일을 맞추므로 줄 수는 같지만 내용이 다른 세그먼트는 변경된 세그먼트로 간주됩니다. 일치하는 세그먼트 사이의 완전히 새로운 라인은 추가 된 세그먼트로 간주됩니다.

이 방법도 아니면 sdiff 명령 줄 도구 단말기에 두 개의 파일의 병렬 비교를 도시하는 동작. 변경된 줄은 | 캐릭터. 파일 A에만 행이 있으면 <가 구분 문자로 사용됩니다. 파일 B에만 행이 있으면>가 분리 자로 사용됩니다. 파일에 <및> 문자가없는 경우이를 사용하여 추가 된 행만 표시 할 수 있습니다.

sdiff A B | grep '[<>]'

2

고마워 senarvi, 귀하의 솔루션 (투표하지 않음)은 실제로 많은 페이지에서 연령대를 찾은 후 내가 원하는 것을 정확하게 제공했습니다.

귀하의 답변을 사용하여 다음은 변경 / 추가 / 삭제 된 항목 목록을 얻기 위해 작성한 것입니다. 이 예에서는 2 가지 버전의 / etc / passwd 파일을 사용하고 관련 레코드의 사용자 이름을 인쇄합니다.

#!/bin/bash
sdiff passwd1 passwd2 | grep '[|]' | awk -F: '{print "changed: " $1}'
sdiff passwd1 passwd2 | grep '[<]' | awk -F: '{print "deleted: " $1}'
sdiff passwd1 passwd2 | grep '[>]' | awk -F\> '{print $2}' | awk -F: '{print "added: " $1}'

"라인이 수정되었습니다"와 "라인이 제거되었고 다른 라인이 그 위 또는 아래에 추가되었습니다"의 차이는 의미 적입니다. 일반적인 텍스트 기반 diff 도구는 이러한 경우를 분리 할 수 ​​없습니다. 결과적으로 sdiff 기반 답변이 모든 경우에 안정적으로 작동하지는 않습니다.
Mikko Rantalainen

0

이 특정 양식이 종종 유용하다는 것을 알았습니다.

diff --changed-group-format='-%<+%>' --unchanged-group-format='' f g

예:

printf 'a\nb\nc\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
     --new-line-format=$'+%l\n' \
     --unchanged-line-format='' \
     f g

산출:

-b
-c
+B
+C
-e
-f
+E
+F

따라서 이전 줄이 표시되고 -그 뒤에 새 줄이 표시됩니다 +.

삭제 한 경우 C:

printf 'a\nb\nd\ne\nf\ng\n' > f
printf 'a\nB\nC\nd\nE\nF\ng\n' > g
diff --old-line-format=$'-%l\n' \
     --new-line-format=$'+%l\n' \
     --unchanged-line-format='' \
     f g

다음과 같이 보입니다 :

-b
+B
+C
-e
-f
+E
+F

형식은 다음에 설명되어 있습니다 man diff.

       --line-format=LFMT
              format all input lines with LFMT`

과:

       LTYPE is 'old', 'new', or 'unchanged'.
              GTYPE is LTYPE or 'changed'.

과:

              LFMT (only) may contain:

       %L     contents of line

       %l     contents of line, excluding any trailing newline

       [...]

관련 질문 : https://stackoverflow.com/questions/15384818/how-to-get-the-difference-only-additions-between-two-files-in-linux

우분투에서 테스트 18.04.


-1

파일 1 :

text670_1
text067_1
text067_2

파일 2 :

text04_1
text04_2
text05_1
text05_2
text067_1
text067_2
text1000_1

사용하다:

diff -y file1 file2

이것은 repectives 파일에 대한 두 개의 열을 보여줍니다.

산출:

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