Команда Linux diff: сравнение файлов

LinuxLinuxBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом практическом занятии (лабораторной работе) мы рассмотрим команду diff, которая является важным инструментом для разработчиков программного обеспечения и системных администраторов, работающих с Linux. Команда diff используется для сравнения содержимого двух файлов и выделения различий между ними. Этот навык особенно ценен при управлении версиями кода, просмотре изменений в конфигурационных файлах или выявлении несоответствий в текстовых данных.

Мы смоделируем сценарий разработки программного обеспечения, в котором вы будете использовать команду diff для сравнения различных версий файлов, что поможет вам понять, как эта команда может быть применена в реальных ситуациях.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL linux(("Linux")) -.-> linux/FileandDirectoryManagementGroup(["File and Directory Management"]) linux(("Linux")) -.-> linux/VersionControlandTextEditorsGroup(["Version Control and Text Editors"]) linux/FileandDirectoryManagementGroup -.-> linux/cd("Directory Changing") linux/VersionControlandTextEditorsGroup -.-> linux/diff("File Comparing") subgraph Lab Skills linux/cd -.-> lab-219189{{"Команда Linux diff: сравнение файлов"}} linux/diff -.-> lab-219189{{"Команда Linux diff: сравнение файлов"}} end

Понимание базового использования команды 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). Другие возможные буквы: a для "добавление" (add) и d для "удаление" (delete).
  • Строки, начинающиеся с <, взяты из первого файла (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-строку и делает первую букву имени заглавной.
  2. Добавлена новая строка (строка 7 в новой версии) с сообщением о благодарности.

Использование объединенного формата

Объединенный формат (опция -u) предоставляет более читаемый вывод, особенно для больших файлов или когда контекст важен.

Сравните 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__":

Разберем этот вывод:

  • Первые две строки показывают сравниваемые файлы и их временные метки (timestamps).
  • Строки, начинающиеся с -, взяты из первого файла (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 заставляет diff рекурсивно сравнивать также поддиректории, что полезно для сравнения сложных структур директорий.

Итог

В этом практическом занятии (лабораторной работе) мы изучили команду diff в Linux в контексте разработки программного обеспечения. Мы научились:

  1. Сравнивать два текстовых файла и интерпретировать базовый вывод команды diff
  2. Сравнивать разные версии Python-скриптов
  3. Использовать объединенный формат для более читаемого вывода
  4. Игнорировать изменения в пробельных символах при сравнении
  5. Рекурсивно сравнивать целые директории

Дополнительные опции команды diff, не рассмотренные в этом практическом занятии, включают:

  • -y: Сравнение в двух колонках (side-by-side comparison)
  • -i: Игнорировать различия в регистре букв
  • -b: Игнорировать изменения в количестве пробельных символов
  • -B: Игнорировать изменения, в которых все строки пустые
  • -q: Сообщать только о различиях между файлами, не показывая сами различия

Эти опции можно комбинировать для более специфических сравнений.