Linux diff 명령어: 파일 비교하기

LinuxBeginner
지금 연습하기

소개

이 실습에서는 Linux 환경에서 소프트웨어 개발자와 시스템 관리자에게 필수적인 도구인 diff 명령어를 살펴봅니다. diff 명령어는 두 파일의 내용을 비교하고 그 차이점을 찾아내는 데 사용됩니다. 이 기술은 코드 버전을 관리하거나, 설정 파일의 변경 사항을 검토하거나, 텍스트 기반 데이터에서 불일치하는 부분을 식별할 때 특히 유용합니다.

우리는 소프트웨어 개발 시나리오를 가정하여 diff 명령어로 서로 다른 버전의 파일을 비교해 보면서, 이 명령어가 실제 상황에서 어떻게 활용되는지 이해해 볼 것입니다.

이 실습은 단계별 안내를 통해 학습과 연습을 돕는 가이드형 실습입니다. 각 단계를 주의 깊게 따라가며 직접 경험을 쌓아보세요. 통계에 따르면 이 실습은 초급 수준이며, 99%의 완료율을 기록하고 있습니다. 또한 학습자들로부터 100%의 긍정적인 평가를 받았습니다.

diff 의 기본 사용법 이해하기

먼저 두 개의 간단한 텍스트 파일을 비교하여 diff 명령어의 기본적인 출력 형식을 이해해 보겠습니다.

우선 프로젝트 디렉토리로 이동합니다.

cd /home/labex/project

이제 diff 명령어를 사용하여 두 파일을 비교해 봅니다.

diff file1.txt file2.txt

다음과 유사한 출력이 나타날 것입니다.

1,2c1,2
< This is version 1 of the file.
< It contains some initial content.
---
> This is version 2 of the file.
> It contains updated content.
4c4
< This is the fourth line.
---
> This is a modified fourth line.

출력 내용을 분석해 보겠습니다.

  • 숫자 (예: 1,2c1,2) 는 변경이 발생한 두 파일의 행 번호를 나타냅니다.
  • 문자 c는 "변경 (change)"을 의미합니다. 다른 문자로 "추가 (add)"를 뜻하는 a, "삭제 (delete)"를 뜻하는 d가 있습니다.
  • <로 시작하는 행은 첫 번째 파일 (file1.txt) 의 내용입니다.
  • >로 시작하는 행은 두 번째 파일 (file2.txt) 의 내용입니다.
  • ---는 첫 번째 파일과 두 번째 파일의 내용을 구분하는 구분선입니다.

이 출력 결과는 다음과 같은 정보를 제공합니다.

  1. 두 파일의 1 행과 2 행이 서로 다릅니다.
  2. 두 파일의 4 행이 서로 다릅니다.
  3. 3 행 (출력에 표시되지 않음) 은 두 파일이 동일합니다.

Python 스크립트 비교하기

이제 diff 명령어를 좀 더 실무적인 시나리오에 적용해 보겠습니다. Python 스크립트를 작성하는 중에 두 가지 버전을 비교해야 하는 상황을 가정해 봅니다.

먼저 두 스크립트 버전의 내용을 확인합니다.

cat script_v1.py

내용은 다음과 같습니다.

def greet(name):
    print("Hello, " + name + "!")

def main():
    name = input("Enter your name: ")
    greet(name)

if __name__ == "__main__":
    main()

이제 두 번째 버전을 확인합니다.

cat script_v2.py

내용은 다음과 같습니다.

def greet(name):
    print(f"Hello, {name.capitalize()}!")

def main():
    name = input("Enter your name: ")
    greet(name)
    print("Thank you for using this script!")

if __name__ == "__main__":
    main()

이제 diff를 사용하여 이 스크립트들을 비교해 봅니다.

diff script_v1.py script_v2.py

다음과 같은 출력이 나타날 것입니다.

2c2
<     print("Hello, " + name + "!")
---
>     print(f"Hello, {name.capitalize()}!")
6a7
>     print("Thank you for using this script!")

이 출력 결과는 다음을 의미합니다.

  1. 2 행이 변경되었습니다. 인사말이 f-string 을 사용하고 이름의 첫 글자를 대문자로 변환하도록 수정되었습니다.
  2. 새로운 행 (새 버전의 7 행) 에 감사 메시지가 추가되었습니다.

통합 형식 (Unified Format) 사용하기

통합 형식 (-u 옵션) 은 특히 파일이 크거나 변경 전후의 맥락 (context) 이 중요할 때 더 읽기 쉬운 출력을 제공합니다.

통합 형식을 사용하여 Python 스크립트를 비교해 봅니다.

diff -u script_v1.py script_v2.py

다음과 같은 출력이 나타날 것입니다.

--- script_v1.py 2023-12-28 10:00:00.000000000 +0000
+++ script_v2.py 2023-12-28 10:05:00.000000000 +0000
@@ -1,8 +1,9 @@
 def greet(name):
-    print("Hello, " + name + "!")
+    print(f"Hello, {name.capitalize()}!")

 def main():
     name = input("Enter your name: ")
     greet(name)
+    print("Thank you for using this script!")

 if __name__ == "__main__":

출력 내용을 분석해 보겠습니다.

  • 처음 두 행은 비교 대상 파일과 해당 파일의 타임스탬프를 보여줍니다.
  • -로 시작하는 행은 첫 번째 파일 (script_v1.py) 에서 제거되거나 수정된 내용입니다.
  • +로 시작하는 행은 두 번째 파일 (script_v2.py) 에서 추가되거나 수정된 내용입니다.
  • -+가 없는 행은 변경되지 않은 부분으로, 변경 사항 주변의 맥락을 보여줍니다.
  • @@ -1,8 +1,9 @@ 행은 첫 번째 파일의 1~8 행과 두 번째 파일의 1~9 행 범위를 보여주고 있음을 나타냅니다.

이 형식은 변경 사항 주변의 맥락을 함께 보여주기 때문에 개발자들이 가장 선호하는 방식입니다.

공백 차이 무시하기

때로는 공백 (스페이스, 탭) 의 차이가 중요하지 않을 때가 있습니다. -w 옵션을 사용하면 diff가 이러한 공백 차이를 무시하도록 설정할 수 있습니다.

공백을 약간 수정한 새로운 버전의 스크립트를 만들어 보겠습니다.

참고: 스크립트에 공백을 직접 추가해야 합니다. 코드를 단순히 복사해서 붙여넣으면 공백 차이가 포함되지 않을 수 있습니다.

cat > script_v3.py << EOF
def greet(name):
    print(f"Hello, {name.capitalize()}!")

def main():
    name = input("Enter your name: ")
    greet(name)
    print("Thank you for using this script!")

if __name__ == "__main__":
    main()
EOF

이제 script_v2.py 와 script_v3.py 를 비교해 봅니다. 먼저 옵션 없이 비교한 후, -w 옵션을 사용하여 비교해 보세요.

diff script_v2.py script_v3.py

공백으로 인해 몇 가지 차이점이 나타날 수 있습니다. 이제 다음을 실행해 보세요.

diff -w script_v2.py script_v3.py

아무런 출력도 나타나지 않을 것입니다. 이는 공백을 무시했을 때 두 파일 사이에 차이점이 없음을 의미합니다.

이 옵션은 코드의 포맷팅 차이보다는 실제 로직의 변경 사항에 집중하고 싶을 때 매우 유용합니다.

디렉토리 비교하기

diff 명령어는 개별 파일뿐만 아니라 디렉토리 전체를 비교할 수도 있습니다. 몇 개의 파일이 들어있는 두 개의 디렉토리를 만들어 비교해 보겠습니다.

디렉토리와 파일을 생성합니다.

echo "This is a file in dir1" > dir1/file.txt
echo "This is a file in dir2" > dir2/file.txt
echo "This file is unique to dir1" > dir1/unique1.txt
echo "This file is unique to dir2" > dir2/unique2.txt

이제 디렉토리를 비교합니다.

diff -r dir1 dir2

다음과 유사한 출력이 나타날 것입니다.

Only in dir1: unique1.txt
Only in dir2: unique2.txt
diff -r dir1/file.txt dir2/file.txt
1c1
< This is a file in dir1
---
> This is a file in dir2

이 출력 결과는 다음을 의미합니다.

  1. dir1에는 unique1.txt라는 파일이 있지만 dir2에는 없습니다.
  2. dir2에는 unique2.txt라는 파일이 있지만 dir1에는 없습니다.
  3. file.txt는 두 디렉토리에 모두 존재하지만 내용이 서로 다릅니다.

-r 옵션은 하위 디렉토리까지 재귀적으로 비교하게 해주므로, 복잡한 디렉토리 구조를 비교할 때 유용합니다.

요약

이 실습에서는 소프트웨어 개발 환경에서 Linux diff 명령어를 사용하는 방법을 살펴보았습니다. 우리가 학습한 내용은 다음과 같습니다.

  1. 두 텍스트 파일을 비교하고 기본적인 diff 출력을 해석하는 방법
  2. Python 스크립트의 서로 다른 버전을 비교하는 방법
  3. 가독성이 좋은 통합 형식 (Unified format) 을 사용하는 방법
  4. 비교 시 공백 차이를 무시하는 방법
  5. 디렉토리 전체를 재귀적으로 비교하는 방법

이 실습에서 다루지 않은 추가적인 diff 옵션들은 다음과 같습니다.

  • -y: 두 파일의 내용을 나란히 (Side-by-side) 비교
  • -i: 대소문자 차이 무시
  • -b: 공백의 개수 차이 무시
  • -B: 빈 줄만 있는 행의 변경 사항 무시
  • -q: 파일의 차이점 상세 내용 없이 차이 여부만 보고

이러한 옵션들을 조합하여 사용하면 상황에 맞는 정밀한 비교가 가능합니다.