Как переслать цветной вывод diff в less?

Вопрос или проблема

Я использовал git diff, который выдает цветной вывод. Однако теперь я должен использовать обычный diff для чего-то, и он выдает много текста, который трудно читать из-за отсутствия цветов. Как сделать, чтобы diff выдавал читаемый, цветной вывод? Идеально, чтобы можно было просматривать большие файлы, пропуская их через less.

Большинство реализаций diff не могут выводить цвет, для этого вам понадобится другая программа, такая как colordiff. Но более новые GNU diffutils имеют опцию --color, так что если вы используете Linux и у вас установлена последняя версия (после v3.4, я думаю), то вы можете сделать это непосредственно с помощью diff. Если ваш diff не поддерживает --color, читайте дальше.

Цвета в терминале выводятся через ANSI-коды управления, которые less по умолчанию не интерпретирует. Чтобы less правильно отображал цвета, вам нужен переключатель -r, или еще лучше, -R:

colordiff -- "$file1" "$file2" | less -R

Из man less:

   -R или --RAW-CONTROL-CHARS
          Как -r, но только для "цветных" ANSI последовательностей
          выводится в "сыром" виде. В отличии от -r, экран
          корректно отображается в большинстве случаев.
          ANSI "цветные" последовательности имеют вид:

               ESC [ ... m

          где "..." может содержать ноль или более символов спецификации цвета.
          Для отслеживания внешнего вида экрана предполагается,
          что ANSI цветные коды не перемещают курсор.
          Можно заставить less думать, что символы, кроме "m", могут завершать
          ANSI цветные последовательности, установив переменную окружения LESSANSIENDCHARS 
          в список символов, которые могут завершать такую последовательность.
          Также можно заставить less думать, что символы, не входящие в стандартный
          набор, могут встречаться между ESC и m, установив переменную окружения
          LESSANSIMIDCHARS в список символов, которые могут появляться.

Альтернативно, вы можете использовать more, который по умолчанию правильно отображает цвета.


Если вы не можете установить внешние программы, вы можете получить тот же результат, используя более ручной подход:

diff a b | 
   perl -lpe 'if(/^</){$_ = "\e[1;31m$_\e[0m"} 
              elsif(/^>/){$_ = "\e[1;34m$_\e[0m"}'

Другие ответы здесь могут устареть. На версии coreutils 3.5 diff действительно может выдавать цветной вывод, который по умолчанию отключен, когда stdout не является консолью.

Из man-страницы:

--color[=WHEN]
цветной вывод; WHEN может быть never, always или auto (по умолчанию)

Чтобы принудительно включить цветной вывод, когда stdout является каналом, команда diff --color=always -- "$file1" "$file2" | less -R должна сработать.

Чтобы направить цветной diff в less:

diff $file1 $file2 | colordiff | less -r

Чтобы сделать его более читаемым, ограничив отображение одним экраном:

diff -uw $file1 $file2 | colordiff | less -r

И чтобы less не отображал, если контент умещается на одном экране:

diff -uw $file1 $file2 | tee /dev/stderr | colordiff | less -r -F

Опция -F заставляет less закрываться сразу, если контент занимает менее одного экрана. Пайп на stderr используется для того, чтобы вывод был виден, даже если less не отображается.

Альтернативный (и, на мой взгляд, лучший) способ — просто использовать -X, чтобы предотвратить очистку экрана less:

diff -uw $file1 $file2 | colordiff | less -r -X -F

Это работает хорошо для меня, но может быть специфично для bash. colordiff не является встроенным, но легко устанавливается.

Я бы использовал riff:

diff "$A" "$B" | riff

Или просто это, что в фоновом режиме вызовет diff:

riff "$A" "$B"

Riff не только указывает, какие строки изменились, но и какие части строк были изменены (см. скриншот ниже).

По умолчанию Riff использует разбиение на страницы так же, как это делает git, так что вам не нужно беспокоиться о интеграции с просмотрщиком.

Кроме того, Riff интегрируется с git, так что вы можете получить такой вывод от git diff и его партнеров тоже.

Вы можете скачать его здесь: https://github.com/walles/riff/releases/

riff в действии

Примечание: Я сам написал riff, поэтому, конечно, я его рекомендую :).

.

Ответ или решение

Чтобы достичь читаемого и цветного вывода командой diff, при этом одновременно просматривать большие файлы с помощью less, я предлагаю несколько решений с учетом вашего контекста.

Проблема

Вы замечаете, что стандартный вывод diff трудно воспринимается из-за отсутствия цветовой индикации для различий. Цель — сделать вывод от diff более читаемым и управляемым с помощью less.

Решение

Использование colordiff

  1. Установка colordiff: Это утилита, которая добавляет цветовые маркеры к выводу команды diff. Установите ее с помощью пакетного менеджера, например, apt на Ubuntu или brew на macOS:

    sudo apt-get install colordiff
    # Или
    brew install colordiff
  2. Пайпинг вывода в less: Используйте следующий синтаксис для того, чтобы вывод оставался цветным в less:

    diff file1.txt file2.txt | colordiff | less -R

    Флаг -R позволяет less корректно обрабатывать ANSI-коды, обеспечивая цветной вывод без перемещения курсора.

Использование GNU diffutils

Если у вас установлена последняя версия GNU diffutils (начиная с версии 3.4), ваша команда diff может иметь возможность цветного вывода. Для этого выполните:

diff --color=always file1.txt file2.txt | less -R

Это обеспечит принудительный цветной вывод даже при использовании пайпов.

Ручное добавление цветов с помощью Perl

В случае, если нет возможности установить дополнительные пакеты, можно использовать Perl для добавления цветовых кодов вручную:

diff file1.txt file2.txt | 
perl -lpe 'if(/^</){$_="\e[1;31m$_\e[0m"}elsif(/^>/){$_="\e[1;34m$_\e[0m"}'

Эти команды подсвечивают строки, которые были добавлены (синим цветом) или удалены (красным цветом).

Альтернативное решение с использованием riff

Если вы ищете более понятное отображение изменений на уровне символов, обратите внимание на утилиту riff, которая делает это прозрачно и с интегрированным пейджингом:

riff file1.txt file2.txt

riff автоматически обрабатывает вывод так, чтобы он был удобен для просмотра, даже при больших объемах данных.

Заключение

Используя одно из вышеперечисленных решений, вы улучшите читаемость вывода команды diff, что значительно упростит анализ отличий в файлах. Integrating these tools will enhance your productivity when dealing with large volumes of data and complex code changes.

Оцените материал
Добавить комментарий

Капча загружается...