텍스트 파일의 두 가지 버전 간의 차이점을 확인해야 할 때, `diff` 명령어는 매우 유용한 도구입니다. 이 튜토리얼에서는 Linux 및 macOS 환경에서 `diff` 명령어를 효과적으로 사용하는 방법을 설명합니다.
차이점 분석
`diff` 명령어는 두 파일을 비교하여 그 차이점을 상세하게 보여줍니다. 특히, 첫 번째 파일을 수정하여 두 번째 파일과 일치시키기 위해 필요한 변경 사항 목록을 생성합니다. 이 점을 이해하면 `diff` 명령어의 출력을 해석하는 데 도움이 됩니다. `diff` 명령어는 주로 소스 코드 파일 간의 차이점을 찾아내고, `patch`와 같은 다른 프로그램에서 사용할 수 있는 형태로 결과를 제공하도록 설계되었습니다. 하지만 여기서는 사람이 이해하기 쉬운 형태로 `diff`를 사용하는 방법을 중점적으로 다룰 것입니다.
두 파일을 비교해 보겠습니다. 명령줄에서 파일의 순서는 `diff`가 어떤 파일을 “첫 번째 파일”로, 어떤 파일을 “두 번째 파일”로 간주할지 결정합니다. 예를 들어, `alpha1`과 `alpha2`라는 두 파일이 있다고 가정합시다. 두 파일 모두 NATO 음성 알파벳을 포함하고 있지만, `alpha2` 파일에는 추가적인 편집이 적용되어 두 파일이 서로 다릅니다.
다음 명령어를 사용하여 두 파일을 비교할 수 있습니다. `diff` 명령어 뒤에 첫 번째 파일 이름, 공백, 두 번째 파일 이름을 차례로 입력한 후 Enter 키를 누릅니다.
diff alpha1 alpha2
출력 결과를 어떻게 분석할 수 있을까요? 각 차이점은 고유한 레이블과 함께 순서대로 표시됩니다. 레이블은 `4c4`와 같이 숫자와 문자 조합으로 구성되어 있습니다. 첫 번째 숫자는 `alpha1` 파일의 줄 번호이고, 두 번째 숫자는 `alpha2` 파일의 줄 번호입니다. 중간의 문자는 다음과 같은 의미를 가집니다.
- `c`: 첫 번째 파일의 해당 줄을 두 번째 파일의 해당 줄과 일치하도록 변경해야 함을 나타냅니다.
- `d`: 첫 번째 파일의 해당 줄을 삭제해야 함을 나타냅니다.
- `a`: 첫 번째 파일에 두 번째 파일과 일치하도록 콘텐츠를 추가해야 함을 나타냅니다.
예를 들어, `4c4` 레이블은 `alpha1` 파일의 네 번째 줄을 `alpha2` 파일의 네 번째 줄과 일치하도록 변경해야 함을 의미합니다. 이것은 두 파일 간의 첫 번째 차이점입니다.
<
로 시작하는 줄은 첫 번째 파일인 `alpha1`을 나타내고, `>`로 시작하는 줄은 두 번째 파일인 `alpha2`를 나타냅니다. 예를 들어, `> Dave`는 `alpha2` 파일의 네 번째 줄 내용이 “Dave”임을 알려줍니다. 따라서 `alpha1` 파일의 네 번째 줄인 “Delta”를 “Dave”로 변경하면 해당 줄이 두 파일에서 일치하게 됩니다.
다음 변경 사항은 `12c12`로 표시됩니다. 이 경우, `alpha1`의 12번째 줄에는 “Lima”라는 단어가 있지만, `alpha2`의 12번째 줄에는 “Linux”라는 단어가 있습니다.
세 번째 변경 사항은 `alpha2`에서 삭제된 줄을 나타냅니다. 레이블 `21d20`은 “두 파일을 20번째 줄부터 동기화하려면 첫 번째 파일에서 21번째 줄을 삭제해야 합니다.”라고 해석할 수 있습니다.
네 번째 차이점은 `26a26,28`로 표시됩니다. 이 변경 사항은 `alpha2`에 추가된 세 개의 줄을 나타냅니다. 레이블의 `26,28`은 26번째 줄부터 28번째 줄까지의 범위를 나타냅니다. 따라서 “첫 번째 파일의 26번째 줄에서 두 번째 파일의 26번째부터 28번째 줄까지의 내용을 추가해야 한다”는 의미입니다. `alpha1`에 추가해야 할 세 줄의 내용은 “Quirk”, “Strange”, “Charm”입니다.
간결한 명령어
만약 두 파일이 동일한지 여부만 알고 싶다면, `-s` 옵션(동일한 파일 보고)을 사용하면 됩니다.
diff -s alpha1 alpha3
두 파일이 서로 다른 경우, `-q` 옵션(간단한)을 사용하면 간결하게 결과를 확인할 수 있습니다.
diff -q alpha1 alpha2
두 파일이 동일할 때 `-q` 옵션은 아무런 결과도 출력하지 않습니다.
대안적인 시각
`-y` 옵션(병렬)을 사용하면 파일 차이점을 나란히 비교할 수 있습니다. 이 옵션과 함께 `-W` 옵션(너비)을 사용하여 출력되는 열 수를 제한하는 것이 좋습니다. 이렇게 하면 긴 줄이 줄바꿈되어 가독성이 떨어지는 것을 방지할 수 있습니다. 다음은 출력 폭을 70열로 제한하여 `alpha1`과 `alpha2` 파일을 나란히 표시하는 명령어입니다.
diff -y -W 70 alpha1 alpha2
명령줄에서 첫 번째 파일인 `alpha1`은 왼쪽에, 두 번째 파일인 `alpha2`는 오른쪽에 표시됩니다. 각 파일의 줄은 나란히 표시되며, 변경, 삭제 또는 추가된 줄 옆에는 특정 기호가 표시됩니다.
- `|`: 두 번째 파일에서 변경된 줄을 나타냅니다.
- `<`: 두 번째 파일에서 삭제된 줄을 나타냅니다.
- `>`: 첫 번째 파일에는 없고 두 번째 파일에 추가된 줄을 나타냅니다.
만약 파일 차이점에 대한 더 간결한 요약을 원한다면, `–suppress-common-lines` 옵션을 사용할 수 있습니다. 이 옵션은 변경, 추가 또는 삭제된 줄만 표시합니다.
diff -y -W 70 --suppress-common-lines alpha1 alpha2
색상 추가
`colordiff`라는 유틸리티를 사용하면 `diff` 출력에 색상 강조 표시를 추가하여 어떤 줄에 차이가 있는지 훨씬 쉽게 파악할 수 있습니다.
Ubuntu 또는 다른 Debian 기반 배포판을 사용하는 경우, `apt-get`을 사용하여 이 패키지를 설치할 수 있습니다. 다른 Linux 배포판에서는 해당 배포판의 패키지 관리 도구를 사용하십시오.
sudo apt-get install colordiff
`colordiff` 사용법은 `diff`와 동일합니다.
실제로 `colordiff`는 `diff`의 래퍼이며, `diff`가 실제 비교 작업을 수행합니다. 따라서 `diff`의 모든 옵션은 `colordiff`에서도 사용할 수 있습니다.
맥락 정보 제공
파일의 모든 줄을 표시하는 것과 변경된 줄만 표시하는 것 사이의 절충안으로, `diff` 명령어에 맥락 정보를 함께 출력하도록 요청할 수 있습니다. 이를 위해 두 가지 방법이 있습니다. 두 방법 모두 변경된 줄 전후에 몇 줄을 추가로 표시하여 변경 사항이 파일의 어떤 위치에서 발생했는지 파악할 수 있도록 합니다.
첫 번째 방법은 `-c` 옵션(복사된 맥락)을 사용하는 것입니다.
colordiff -c alpha1 alpha2
`diff` 출력에는 헤더가 포함되어 있으며, 헤더에는 두 개의 파일 이름과 수정 시간이 표시됩니다. 별표(`*`)와 대시(`-`)는 출력 줄이 속한 파일을 나타내는 데 사용됩니다. 첫 번째 파일 이름 앞에는 별표가, 두 번째 파일 이름 앞에는 대시가 있습니다.
예를 들어, `* 1,7 *` 줄은 `alpha1`의 1번째 줄부터 7번째 줄까지를 보여주고 있음을 나타냅니다. 이 중에서 “Delta”라는 단어가 변경된 것으로 표시됩니다. 변경된 줄 앞뒤로 세 줄의 변경되지 않은 텍스트가 함께 표시되어 해당 줄의 맥락을 보여줍니다.
중간에 `— 1,7 —` 줄이 있으면, 현재 `alpha2` 파일의 1번째 줄부터 7번째 줄까지를 보고 있다는 것을 알려줍니다. 마찬가지로, 4번째 줄의 “Dave”라는 단어가 변경된 것으로 표시됩니다.
colordiff -C 2 alpha1 alpha2
기본적으로 각 변경 사항의 위아래로 세 줄의 맥락이 표시되지만, `-C` 옵션을 사용하여 표시할 맥락 줄 수를 지정할 수 있습니다.
colordiff -u alpha1 alpha2
맥락을 제공하는 두 번째 방법은 `-u` 옵션(통합 맥락)을 사용하는 것입니다.
출력에는 파일 이름과 수정 시간이 포함된 헤더가 있습니다. `alpha1` 이름 앞에는 대시(`-`)가, `alpha2` 이름 앞에는 더하기 기호(`+`)가 있습니다. 이는 대시가 `alpha1`을, 더하기 기호가 `alpha2`를 나타내는 데 사용됨을 의미합니다. 출력 중간중간에 at 기호(`@`)로 시작하는 줄이 있는데, 이 줄은 각 차이점의 시작을 표시하고 각 파일에서 어떤 줄을 표시하는지 알려줍니다.
변경된 줄 전후로 세 줄이 표시되어 변경 사항의 맥락을 보여줍니다. 통합 보기에서는 차이가 있는 줄이 위아래로 표시됩니다. `alpha1`의 줄 앞에는 대시가, `alpha2`의 줄 앞에는 더하기 기호가 붙습니다. 이러한 방식은 복사된 맥락 방식보다 더 적은 줄로 동일한 정보를 제공할 수 있습니다.
colordiff -U 2 alpha1 alpha2
통합 맥락에서 표시할 줄 수 지정
통합 맥락에서 표시할 줄 수를 정확히 지정하려면 `-U` 옵션을 사용하고 원하는 줄 수를 입력합니다.
공백 및 대소문자 무시
colordiff -y -W 70 test4 test5
`test4`와 `test5`라는 두 파일을 분석해 보겠습니다. 이 파일에는 6명의 슈퍼히어로 이름이 들어 있습니다.
결과를 보면 `diff` 명령어가 “Black Widow”, “Spider-Man”, “Thor” 줄에서는 차이점을 찾지 못하고, “Captain America”, “Ironman”, “The Hulk” 줄에서만 차이점을 찾았습니다. 그렇다면 차이점은 무엇일까요? `test5` 파일에서 “The Hulk”는 소문자 “h”로 시작하고, “Captain America”는 “Captain”과 “America” 사이에 추가 공백이 있습니다. “Ironman” 줄에는 눈에 띄는 차이가 없습니다. 눈에 보이는 차이가 없다면, 공백 문자가 원인일 가능성이 높습니다. 해당 줄 끝에 공백 또는 탭 문자가 있을 수 있습니다.
이러한 차이점이 중요하지 않다면, `diff` 명령어에 특정 유형의 줄 차이를 무시하도록 지시할 수 있습니다.
- `-i`: 대소문자 차이를 무시합니다.
- `-Z`: 후행 공백을 무시합니다.
- `-b`: 공백 개수 변화를 무시합니다.
- `-w`: 모든 공백 변화를 무시합니다.
colordiff -i -y -W 70 test4 test5
대소문자 차이를 무시하고 다시 비교해 보겠습니다.
colordiff -i -Z -y -W 70 test4 test5
이제 “The Hulk”와 “The hulk” 줄은 동일하게 간주되며, 소문자 “h” 차이에 대한 차이점이 표시되지 않습니다. 후행 공백도 무시하도록 요청해 보겠습니다.
colordiff -i -w -y -W 70 test4 test5
예상대로 `diff`는 더 이상 해당 줄에 대한 차이를 표시하지 않으므로 후행 공백이 “Ironman” 줄의 차이였을 가능성이 큽니다. “Captain America”만 남았습니다. 대소문자를 무시하고 모든 공백 문제를 무시하도록 요청해 보겠습니다.
우리가 중요하게 생각하지 않는 차이점을 무시하도록 `diff` 명령어에 지시하면, 우리의 목적에 맞게 두 파일이 일치한다는 것을 알 수 있습니다. `diff` 명령어에는 더 많은 옵션이 있지만, 대부분은 기계가 읽을 수 있는 결과를 생성하는 것과 관련이 있습니다. 자세한 내용은 Linux 매뉴얼 페이지를 참조하십시오.
위에서 사용한 옵션들을 활용하면, 명령줄과 사람의 눈을 사용하여 텍스트 파일 버전 간의 모든 차이점을 쉽게 추적할 수 있습니다.