개요

컴퓨터에서 diff는 두 개의 파일 간 차이에 대한 정보를 출력하는 파일 비교 유틸리티이다. 일반적으로 하나의 파일 버전과 동일한 파일의 다른 버전 간의 변경 사항을 보여주는 데 쓰인다. diff는 문서 파일의 줄 사이 변경 사항을 보여준다. 이 명령어로 만든 파일은 유닉스 계열 프로그램인 patch 명령어를 이용하여 출력물을 생성할 수 있다.

역사

diff 유틸리티는 1970년대 초에 AT&T 벨 연구소와 병합 중이던 유닉스 운영 체제 상에서 개발되었다. 최종 버전은 1974년의 유닉스 제5판에 더글라스 맥클로이(Douglas McIlroy)가 완전히 다시 쓴 판이다.

알고리즘

diff 명령은 최장 공통 부분 수열 문제를 해결하는 데 기반을 둔다.

이 문제에서 다음과 같이 두 개의 항목이 있다고 가정하자.

       a b c d f g h j q z
       a b c d e f g i j k r x y z

여기서 공통이 되는 가장 긴 부분은 다음과 같다.

       a b c d f g j z

두 개의 항목을 비교하여 추가(+ 기호로 표시)되거나 삭제(- 기호로 표시)되는 부분들은 다음과 같이 나타낸다.

       e   h i   q   k r x y
       +   - +   -   + + + +

사용법

명령 줄에 다음과 같이 두 개의 파일 이름을 지정한다.

diff [원본 파일 이름 또는 원본 디렉터리 이름] [새 파일 이름 또는 새 디렉터리 이름]

이는 원본 파일이 새 파일이 될 것임을 가리킨다. 디렉터리로 지정할 경우 diff는 두 디렉터리에 존재하는 각 파일마다 차이점을 분석한다. -r 옵션을 이용하면 하부 디렉터리까지 검색한다.

원본 파일과 새 파일의 내용이 다음과 같다고 가정하자.

  

원본 파일:

1  This part of the
2  document has stayed the
3  same from version to
4  version.  It shouldn't
5  be shown if it doesn't
6  change.  Otherwise, that
7  would not be helping to
8  compress the size of the
9  changes.
10
11 This paragraph contains
12 text that is outdated.
13 It will be deleted in the
14 near future.
15
16 It is important to spell
17 check this dokument. On
18 the other hand, a
19 misspelled word isn't
20 the end of the world.
21 Nothing in the rest of
22 this paragraph needs to
23 be changed. Things can
24 be added after it.
  

새 파일:

1  This is an important
2  notice! It should
3  therefore be located at
4  the beginning of this
5  document!
6
7  This part of the
8  document has stayed the
9  same from version to
10 version.  It shouldn't
11 be shown if it doesn't
12 change.  Otherwise, that
13 would not be helping to
14 compress anything.
15
16 It is important to spell
17 check this document. On
18 the other hand, a
19 misspelled word isn't
20 the end of the world.
21 Nothing in the rest of
22 this paragraph needs to
23 be changed. Things can
24 be added after it.
25
26 This paragraph contains
27 important new additions
28 to this document.

이 경우 diff 명령은 두 개 파일의 내용을 비교하여 다음과 같은 차이점을 만들어낸다.

0a1,6
> This is an important
> notice! It should
> therefore be located at
> the beginning of this
> document!
>
8,14c14
< compress the size of the
< changes.
<
< This paragraph contains
< text that is outdated.
< It will be deleted in the
< near future.
---
> compress anything.
17c17
< check this dokument. On
---
> check this document. On
24c24,28
< be added after it.
---
> be added after it.
>
> This paragraph contains
> important new additions
> to this document.

전통적인 출력 방식에서 aadded(추가)를 가리키고, ddeleted(삭제)를, 그리고 cchanged(변경)을 가리킨다. 원본 파일의 줄 수는 a/d/c 앞에 나타나고, 수정되는 파일의 줄 수는 그 뒤에 나타난다.

기본적으로 두 개의 파일에 내용이 완전히 일치하는 줄은 나타나지 않는다.[1]

종류

1975년 이후로 핵심 알고리즘의 개선, 명령어로의 유용한 기능 추가, 새로운 출력 포맷 설계 등이 변경 사항에 포함되었다.

편집 스크립트

-e 옵션을 이용하면 현대 버전의 diff를 통해 편집 스크립트를 만들어낼 수 있다. 결과는 이를테면 다음과 같다:

 24a

 This paragraph contains
 important new additions
 to this document.
 .
 17c
 check this document. On
 .
 8,14c
 compress anything.
 .
 0a
 This is an important
 notice! It should
 therefore be located at
 the beginning of this
 document!

 .

환경 포맷

BSD는 환경 포맷 (-c)을 추가하고 파일시스템 디렉터리 구조 리커스 기능 (-r)을 1981년 7월에 2.8 BSD에 추가하여 출시하였다. 버클리가 도입한 diff의 환경 포맷은 사소하게 변경된 소스 코드의 패치를 배포하는 데 큰 도움이 되었다.

diff -c [원본 파일] [새 파일]을 이용하면 다음과 같은 출력물을 만들어낸다:

*** /path/to/original ''timestamp''
--- /path/to/new ''timestamp''
***************
*** 1,3 ****
--- 1,9 ----
+ This is an important
+ notice! It should
+ therefore be located at
+ the beginning of this
+ document!
+
  This part of the
  document has stayed the
  same from version to
***************
*** 5,20 ****
  be shown if it doesn't
  change.  Otherwise, that
  would not be helping to
! compress the size of the
! changes.
!
! This paragraph contains
! text that is outdated.
! It will be deleted in the
! near future.

  It is important to spell
! check this dokument. On
  the other hand, a
  misspelled word isn't
  the end of the world.
--- 11,20 ----
  be shown if it doesn't
  change.  Otherwise, that
  would not be helping to
! compress anything.

  It is important to spell
! check this document. On
  the other hand, a
  misspelled word isn't
  the end of the world.
***************
*** 22,24 ****
--- 22,28 ----
  this paragraph needs to
  be changed. Things can
  be added after it.
+
+ This paragraph contains
+ important new additions
+ to this document.

통일 포맷

통일 포맷 (unidiff)은 환경 포맷의 기술적 개선을 그대로 이어받았으나 비교되는 두 파일에 대한 조그마한 diff를 만들어낸다. 통일 포맷은 -u 옵션을 사용하여 이용할 수 있다. 이 출력물은 patch 프로그램의 입력에 쓰인다.

통일 환경의 diff는 1990년 8월 웨인 데이비슨이 unidiff라는 이름으로 처음 개발하였다. 리처드 스톨만이 1개월 뒤 GNU 프로젝트의 diff 유틸리티에 통일 diff 지원을 추가하면서 1991년 1월 GNU diff 1.15에 이 기능이 들어갔다.

diff -u [원본 파일] [새 파일]을 이용하면 다음과 같은 출력물을 만들어낸다:

--- /path/to/original ''timestamp''
+++ /path/to/new ''timestamp''
@@ -1,3 +1,9 @@
+This is an important
+notice! It should
+therefore be located at
+the beginning of this
+document!
+
 This part of the
 document has stayed the
 same from version to
@@ -5,16 +11,10 @@
 be shown if it doesn't
 change.  Otherwise, that
 would not be helping to
-compress the size of the
-changes.
-
-This paragraph contains
-text that is outdated.
-It will be deleted in the
-near future.
+compress anything.

 It is important to spell
-check this dokument. On
+check this document. On
 the other hand, a
 misspelled word isn't
 the end of the world.
@@ -22,3 +22,7 @@
 this paragraph needs to
 be changed. Things can
 be added after it.
+
+This paragraph contains
+important new additions
+to this document.

기타

이 밖에도 sdiff과 diffmk가 존재한다.