Сравнение папок с файлами в линукс. Как сравнить файлы по содержимому в Windows или Linux? Синтаксис команды аналогичен синтаксису diff



Сравнение двух файлов в терминале linux (6)

Вот мое решение для этого:

Mkdir temp mkdir results cp /usr/share/dict/american-english ~/temp/american-english-dictionary cp /usr/share/dict/british-english ~/temp/british-english-dictionary cat ~/temp/american-english-dictionary | wc -l > ~/results/count-american-english-dictionary cat ~/temp/british-english-dictionary | wc -l > ~/results/count-british-english-dictionary grep -Fxf ~/temp/american-english-dictionary ~/temp/british-english-dictionary > ~/results/common-english grep -Fxvf ~/results/common-english ~/temp/american-english-dictionary > ~/results/unique-american-english grep -Fxvf ~/results/common-english ~/temp/british-english-dictionary > ~/results/unique-british-english

Есть два файла с именем «a.txt» и «b.txt», у которых есть список слов. Теперь я хочу проверить, какие слова добавлены в «a.txt» и не находятся в «b.txt» .

Мне нужен эффективный алгоритм, так как мне нужно сравнить два словаря.

Вы можете использовать инструмент diff в linux для сравнения двух файлов. Для фильтрации требуемых данных вы можете использовать опции --changed-group-format и --unchanged-group-format .

Следующие три варианта могут использовать для выбора соответствующей группы для каждой опции:

    "% <" получить строки из FILE1

    "%>" получает строки из FILE2

    "" (пустая строка) для удаления строк из обоих файлов.

Например: diff --changed-group-format = "% <" --unchanged-group-format = "" file1.txt file2.txt

[ tmp]# cat file1.txt test one test two test three test four test eight [ tmp]# cat file2.txt test one test three test nine [ tmp]# diff --changed-group-format="%<" --unchanged-group-format="" file1.txt file2.txt test two test four test eight

Если вы предпочитаете стиль вывода diff из git diff , вы можете использовать его с флагом --no-index для сравнения файлов не в репозитории git:

Git diff --no-index a.txt b.txt

Используя пару файлов с строками имени файла размером 200 тыс. В каждом, я сравнивал (со встроенной командой time) этот подход и некоторые другие ответы здесь:

Git diff --no-index a.txt b.txt # ~1.2s comm -23 <(sort a.txt) <(sort b.txt) # ~0.2s diff a.txt b.txt # ~2.6s sdiff a.txt b.txt # ~2.7s vimdiff a.txt b.txt # ~3.2s

comm кажется, является самым быстрым на сегодняшний день, тогда как git diff --no-index представляется самым быстрым подходом для вывода в стиле diff.

Обновление 2018-03-25 Фактически вы можете опустить флаг --no-index если вы не находитесь в репозитории git и хотите сравнить невоспроизводимые файлы в этом репозитории. С man-страниц :

Эта форма предназначена для сравнения данных двух путей в файловой системе. Вы можете опустить параметр -no-index при запуске команды в рабочем дереве, контролируемом Git, и по крайней мере одну из точек пути за пределами рабочего дерева или при запуске команды за пределами рабочего дерева, управляемого Git.

Используйте comm -13 (требуется отсортированные файлы) :

$ cat file1 one two three $ cat file2 one two three four $ comm -13 <(sort file1) <(sort file2) four

Сортируйте их и используйте comm:

Comm -23 <(sort a.txt) <(sort b.txt)

comm сравнивает (сортирует) входные файлы и по умолчанию выводит три столбца: строки, которые уникальны для a, строки, которые являются уникальными для b, и строки, которые присутствуют в обоих. Указав -1 , -2 и / или -3 вы можете подавить соответствующий вывод. Поэтому comm -23 ab перечисляет только записи, которые являются уникальными для a. Я использую синтаксис <(...) для сортировки файлов на лету, если они уже отсортированы, вам это не нужно.

если у вас установлен vim, попробуйте следующее:

Vimdiff file1 file2

Vim -d file1 file2

вы найдете его фантастическим.

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

В этой статье мы рассмотрим как выполняется сравнение файлов Linux. Разберем самые полезные способы, как для терминала, так и в графическом режиме. Сначала рассмотрим как выполнять сравнение файла linux с помощью утилиты diff.

  • Сравнение файлов diff

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

    $ diff опции файл1 файл2

    Можно передать больше двух файлов, если это нужно. Перед тем как перейти к примерам, давайте рассмотрим опции утилиты:

    • -q - выводить только отличия файлов;
    • -s - выводить только совпадающие части;
    • - выводить нужное количество строк после совпадений;
    • -u - выводить только нужное количество строк после отличий;
    • -y - выводить в две колонки;
    • -e - вывод в формате ed скрипта;
    • -n - вывод в формате RCS;
    • -a - сравнивать файлы как текстовые, даже если они не текстовые;
    • -t - заменить табуляции на пробелы в выводе;
    • -l - разделить на страницы и добавить поддержку листания;
    • -r - рекурсивное сравнение папок;
    • -i - игнорировать регистр;
    • -E - игнорировать изменения в табуляциях;
    • -Z - не учитывать пробелы в конце строки;
    • -b - не учитывать пробелы;
    • -B - не учитывать пустые строки.

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

    • a - добавлена;
    • d - удалена;
    • c - изменена.

    К тому же, линии, которые отличаются, будут обозначаться символом <, а те, которые совпадают - символом >.

    Вот содержимое наших тестовых файлов:

    Теперь давайте выполним сравнение файлов diff:
    $ diff file1 file2

    В результате мы получим строчку: 2,3c2,4. Она означает, что строки 2 и 3 были изменены. Вы можете использовать опции для игнорирования регистра:
    $ diff -i file1 file2

    Можно сделать вывод в две колонки:
    $ diff -y file1 file2

    А с помощью опции -u вы можете создать патч, который потом может быть наложен на такой же файл другим пользователем:
    $ diff -u file1 file2

    Чтобы обработать несколько файлов в папке удобно использовать опцию -r:
    $ diff -r ~/tmp1 ~/tmp2

    Для удобства, вы можете перенаправить вывод утилиты сразу в файл:
    $ diff -u file1 file2 > file.patch

    Как видите, все очень просто. Но не очень удобно. Более приятно использовать графические инструменты.

    Сравнение файлов Linux с помощью GUI

    Существует несколько отличных инструментов для сравнения файлов в linux в графическом интерфейсе. Вы без труда разберетесь как их использовать. Давайте рассмотрим несколько из них:

    1. Kompare

    Kompare - это графическая утилита для работы с diff, которая позволяет находить отличия в файлах, а также объединять их. Написана на Qt и рассчитана в первую очередь на KDE. Вот ее основные особенности:

  • Поддержка нескольких форматов diff;
  • Поддержка сравнение файла linux и каталогов;
  • Поддержка просмотра файлов diff;
  • Настраиваемый интерфейс;
  • Создание и применение патчей к файлам.

2. DiffMerge

DiffMerge - это кроссплатформенная программ для сравнения и объединения файлов. Позволяет сравнивать два или три файла. Поддерживается редактирование строк на лету.

Особенности:

  • Поддержка сравнения каталогов;
  • Интеграция с просмотрщиком файлов;
  • Настраиваемая.

3. Meld

Это легкий инструмент для сравнения и объединения файлов. Он позволяет сравнивать файлы, каталоги, а также выполнять функции системы контроля версий. Программа создана для разработчиков и имеет такие особенности:

  • Сравнение двух и трех файлов;
  • Использование пользовательских типов и слов;
  • Режим автоматического слияния и действия с боками текста;
  • Поддержка Git, Mercurial, Subversion, Bazar и многое другое.

4. Diffuse

Diffuse - еще один популярный и достаточно простой инструмент для сравнения и слияния файлов. Он написан на Python. Поддерживается две основные возможности - сравнение файлов и управление версиями. Вы можете редактировать файлы прямо во время просмотра. Основные функции:

  • Подсветка синтаксиса;
  • Сочетания клавиш для удобной навигации;
  • Поддержка неограниченного числа отмен;
  • Поддержка Unicode;
  • Поддержка Git, CVS, Darcs, Mercurial, RCS, Subversion, SVK и Monotone.

5. XXdiff

XXdiff - это свободный и очень мощный инструмент для сравнения и слияния файлов. Но у программы есть несколько минусов. Это отсутствие поддержки Unicode и редактирования файлов.

Особенности:

  • Поверхностное или рекурсивное сравнение одного или двух файлов и каталогов;
  • Подсветка отличий;
  • Интерактивное объединение;
  • Поддержка внешних инструментов сравнения, такие как GNU Diff, SIG Diff, Cleareddiff и многое другое;
  • Расширяемость с помощью сценариев;
  • Настраиваемость.

6. KDiff3

KDiff3 - еще один отличный, свободный инструмент для сравнения файлов в окружении рабочего стола KDE. Он входит в набор программ KDevelop и работает на всех платформах, включая Windows и MacOS. Можно выполнить сравнение двух файлов linux для двух или трех, или даже сравнить каталоги. Вот основные особенности:

  • Отображение различий построчно и посимвольно;
  • Поддержка автослияния;
  • Обработка конфликтов при слиянии;
  • Поддержка Unicode;
  • Отображение отличий;
  • Поддержка ручного выравнивания.

В операционной системе Linux есть несколько программных решений для сравнения внутреннего содержимого двух файлов различными методами. Безусловно, такая функция будет безумно полезна веб-разработчику для сравнения двух текстовых файлов. К примеру, есть 2 файла стилей css, которые Вам нужно быстро сравнить чтобы найти в них отличия. Или посмотреть, что нового в обновленном PHP скрипте.

Наглядный пример из жизни:

Итак, в моём случае мне нужно сравнить 2 файла bootstrap.css . Летом сего года я что-то исправил в стилях файла bootstrap.css (чего делать нельзя было, т.к. для кастомных правок стилей нужно использовать отдельный style.css). Из-за этой мелочи мне проблематично обновиться с версии 3.3.2 до bootstrap 3.3.5, т.к. в более новой версии свой обнолённый CSS файл, при замене которого все мои правки пропадут и "слетит" часть дизайна веб-сайта. Учитывая, что в файле стилей bootstrap более 6000 строчек кода абсолютно невозможно самостоятельно просмотреть изменения.

Сравниваем файлы с утилитой diff в linux:

Чтобы сравнить файлы `bootstrap.css" и `bootstrap-original.css" (для наглядности переименовал оригинальный файл, дописав к нему приставочку -original), введите в терминале: $ diff bootstrap.css bootstrap-original.css В консоли мы получили стандартный отчет о различиях в этих файлах. Если нужно автоматически сохранить отчет в отдельный файл на диске - направляем вывод результатов diff в файл $ diff bootstrap.css bootstrap-original.css > сss-modifications.diff Теперь весь отчет о различиях файлов сохранится в этот же папке под именем "сss-modifications.diff ". Однако, такой вывод не слишком наглядно показывает где и что было добавлено или убрано мною. Чтобы яснее увидеть чем отличаются два файла, можно использовать sdiff ; Отличие этого пакета в том, что он не генерирует отчёт о различиях. Расположив оба файла в две колонки, он сразу же показывает отличия в обоих файлах. `|" помечает строки, которые различаются между собой `" подсвечивает строки, которые встречаются только во втором файле.

Синтаксис команды аналогичен синтаксису diff:

$ sdiff bootstrap.css bootstrap-original.css Выводим в консоль различия, а командой: $ sdiff bootstrap.css bootstrap-original.css > сss-modifications.diff Записываем весь отчёт в отдельном файле. Я бы еще посоветовал дописать аргумент -t, для более читабельного формата diff отчёта (достигается путем выравнивания расстояний между таблицами пробелами). В противном случае в gedit стандартный отчет откроется отлично, а в Sublime он "расплывётся": $ sdiff bootstrap.css bootstrap-original.css > сss-modifications.diff -t P.S. на этом возможности сравнения файлов в Linux не заканчиваются и можно сравнить даже 3 файла одновременно. Для этого используйте команду Для одновременного сравнения трех файлов используйте diff3. $ diff3 bootstrap.css bootstrap-original.css bootstrap-3.css > new.diff

), их сравнений, а также сравнений GUI-клиентов для них. Также были обсуждения плагинов к IDE для работы с git и mercurial. Но практически не было информации об инструментах визуального сравнения и разрешения конфликтов слияния.

Недавно я «перескочил» с mercurial (который до сих пор считаю более удобным и логичным) на git, потому что, подавляющее большинство проектов, которые мне интересны, используют git и хостятся на github. В связи с этим, встал вопрос о пересмотре арсенала инструментов, в частности вопрос выбора инструмента визуального сравнения и слияния (diff and merge). Дабы восполнить недостаток информации на хабре, я решил написать этот мини-обзор. Как говориться - по горячим следам.

Под катом Вы также найдете примеры настроек Git для использования с DiffMerge и WinMerge под Windows. Думаю многим сэкономит время.

Название Особенности Платформа

KDiff3

Git и WinMerge

1) Добавим в директорию c:/Git/libexec/git-core/mergetools/
файл winmerge следующего содержания:

Diff_cmd () { "c:/Program Files (x86)/WinMerge/WinMergeU.exe" \ "$LOCAL" "$REMOTE" >/dev/null 2>&1 } merge_cmd () { "c:/Program Files (x86)/WinMerge/WinMergeU.exe" \ "$PWD/$LOCAL" "$PWD/$REMOTE" "$PWD/$MERGED" >/dev/null 2>&1 status=$? }
Когда Git не может автоматически объединить изменения, происходит конфликт слияния и в конфликтующий файл добавляются маркеры слияния (<<<<<<<, =======, и >>>>>>>). Они необходимы для разрешения конфликта с помощью сторонних инструментов.
Рассмотрим файл readme.txt который образуется в результате выполнения слияния веток master и new в приведенном выше примере:

<<<<<<< HEAD master str ======= new str >>>>>>> new
Мы можем открыть файл конфликтов с помощью программы WinMerge для разрешения конфликта.

После этого откроется средство двухстороннего слияния:

Исходя из описанной логики перепишем команду слияния merge_cmd следующим образом:
merge_cmd () { "c:/Program Files (x86)/WinMerge/WinMergeU.exe" \ "$MERGED" >/dev/null 2>&1 status=$? }
По сути, оба приведенных варианта эквивалентны.

2) Отредактируем .gitconfig
tool = winmerge cmd = "winmerge" tool = winmerge cmd = "winmerge" trustExitCode = false keepBackup = false
последняя строчка отменяет сохранение backup-файлов в директории репозитория.

3) Создадим конфликт при слиянии двух веток (см. пример с использованием DiffMerge).
git difftool master new // сравним две ветви

Для разрешения конфликта при слиянии веток, воспользуемся командой
git mergetool

Для сравнения двух или нескольких файлов в Linux есть команда diff. Она может сравнивать как отдельные файлы, так и каталоги. Рассмотрим синтаксис, опции команды diff и несколько примеров использования.

Синтаксис команды diff

Команда diff имеет следующий синтаксис:

Diff [опции] файлы-или-директории

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

Опции команды diff

Рассмотрим основные опции команды diff. Я рассмотрю только те опции, которые сам использую наиболее часто.

-E игнорировать изменения, связанные с добавлением символа табуляции в тексте.
-b игнорировать изменения, связанные с добавлением пробелов.
-w игнорировать изменения, связанные с добавлением пробелов и табуляции.
-B игнорировать новые пустые строки.
-p (или —show-c-function) показать название функции языка C, в которой найдены изменения.
-y (или —side-by-side) отобразить результаты в две колонки.
-r просматривать каталоги рекурсивно.
-X FILE исключить из поиска файлы, имена которых совпадают с шаблонами в файле FILE.
-d (или —minimal) попытаться найти как можно меньше изменений (то есть исключить ложные срабатывания).

Примеры использования команды diff

Сравнение двух текстовых файлов

Для простого сравнения двух текстовых файлов с именами myfile1 и myfile2 выполним в терминале команду:

Diff myfile1 myfile2

Вывод команды diff удобно перенаправить в файл с расширением diff . Большинство текстовых редакторов в Linux, например Gedit, распознают этот файл и подсвечивают его синтаксис. Чтобы направить результат сравнения в файл changes.diff нужно использовать символ перенаправления потока (>):

Diff myfile1 myfile2 > changes.diff

Сравнение директорий, содержащих текстовые файлы

Рассмотрим пример сравнения двух директорий (mydir1 и mydir2), которые содержат текстовые файлы. Основное отличие здесь от примера выше состоит в том, что мы добавим опцию -r, означающую рекурсивный обход файлов в директориях.

Diff -r mydir1 mydir2 > changes.diff

Теперь предположим, что в директориях, в которых мы сравниваем файлы, находится много «мусора», который мы не должны сравнивать. Создадим файл excludeFiles и запишем в него шаблоны и названия файлов, которые мы не должны сравнивать. Например, содержимое excludeFiles может иметь вид:

*.o ChangeLog* *.bak *.exe

Теперь укажем команде diff, чтобы она использовала наш файл excludeFiles при сравнении каталогов:

Diff -r -X excludeFiles mydir1 mydir2 > changes.diff

Таким образом, мы сравниваем файлы, имена которых не попадают под шаблоны в файле excludeFiles, например, vasya.exe или ChangeLog12.

Добавим еще несколько опций, которые описаны выше, чтобы улучшить результат сравнения:

Diff -rwBd -X excludeFiles mydir1 mydir2 > changes.diff

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

Заключение

Дополнительную информацию по использованию команды diff в вашей системе Linux вы можете получить, выполнив команду:

Man diff

Также существуют программы, которые позволяют сравнивать файлы, используя графический интерфейс. Например, программа Meld , которая в наглядном виде показывает где и что изменилось в файлах.