Як розфарбувати diff у командному рядку?


503

Якщо у мене є різниця, як я можу розфарбувати його так, щоб він добре виглядав? Я хочу, щоб це було в командному рядку, тому, будь ласка, ніяких GUI-рішень.


6
Якась конкретна операційна система / оболонка?
Роуленд Шоу

4
Спробуйте github.com/walles/riff . Як додатковий бонус, він виділяє, які частини рядків змінилися.
Йохан Уоллес

Відповіді:


608

Сторінки для diffчоловіків не пропонують рішення для колоризації всередині себе. Подумайте про використання colordiff. Це обгортка, diffяка дає такий же вихід, як і diff, за винятком того, що він збільшує вихід, використовуючи кольорове виділення синтаксису для підвищення читабельності:

diff old new | colordiff

або просто:

colordiff old new

Установка:

  • Ubuntu / Debian: sudo apt-get install colordiff
  • OS X: brew install colordiffабоport install colordiff

45
Щойно знайшов це сам :-). Використовуючи це less -R, можна відобразити послідовність евакуації кольорів у менший розмір.
Даніель Куллманн

34
Можна просто використовувати синтаксис: colordiff file1 file2
Феліпе Альварес

3
На жаль, це не працює для виводу з боку ( -yопція для включення)vimdiffПропозиція нижче, мабуть, кращий спосіб
Привіт-Ангел

8
colordiffдобре працює svn diff | colordiff(тобто в ситуаціях, коли у вас є лише diff, а не два файли, що відрізняються).
Cornstalks

8
Як оновлення до коментаря @ Hi-Angel: colordiff було оновлено і тепер включає -yпідтримку ( ).
Бейлі Паркер

333

Використовуйте Vim :

diff /path/to/a /path/to/b | vim -R -

Або ще краще, VimDiff (або vim -d, який коротший на тип), покаже відмінності між двома, трьома або чотирма файлами поряд.

Приклади:

vim -d /path/to/[ab]

vimdiff file1 file2 file3 file4

7
@Jichao: Я вважаю за краще вчити команди, а не псевдонімувати їх подалі. Таким чином я можу використовувати їх де завгодно, навіть коли мої dotfiles недоступні.
Johnsyweb

1
@AquariusPower: ctrl-cта ctrl-xінші можливості використання у Vim. ctrl-qзахоплюється багатьма терміналами. Див. Розділ Написання та завершення роботи, щоб знайти спосіб, який найкраще відповідає вашим потребам.
Johnsyweb

1
По-перше, що це за оболонка? zsh? Я не розпізнаю =(...)конструкцію. По-друге, я мав diff -ur a bна увазі.
x-yuri


1
Це рішення краще, ніж прийнята відповідь, оскільки не вимагає від вас системного права адміністратора та встановлення будь-якого додаткового інструменту
amanzoor

173

Насправді, здається, є ще один варіант (який я нещодавно помітив, коли стикався з описаною вище проблемою):

git diff --no-index <file1> <file2>
# output to console instead of opening a pager
git --no-pager diff --no-index <file1> <file2>

Якщо у вас є Git (який ви вже можете використовувати), ви зможете використовувати його для порівняння, навіть якщо самі файли не знаходяться під контролем версій. Якщо для вас за замовчуванням не включено, ввімкнути підтримку кольорів тут, здається, значно простіше, ніж деякі раніше згадані обхідні шляхи.


19
Це акуратно, але, на жаль, це не працює, коли входи - це труби. Наприклад, порівняння бінарних файлів через git diff <(xxd file1) <(xxd filed)не працює.
Майкл Андерсон

8
Як не дивно, щонайменше один з файлів повинен бути "поза поточним сховищем", згідно з git help diff. Тож якщо ваш git diff виходить порожнім, спробуйте cd, де ви знаходитесь.
Поганий запит

7
Щоб увімкнути кольори для git diff:git config color.diff auto
JWhy

2
супер просто та швидко
EE33

31
Якщо обидва файли знаходяться у поточному сховищі, використовуйте git diff --no-indexдля порівняння двох файлів.
Олів'є 'Ельбаум' Шерлер

94

diff --color опція додана до дифузолів GNU 3.4 (2016-08-08)

Це за замовчуванням diff реалізація за для більшості дистрибутивів, яка незабаром її отримує.

Ubuntu 18.04 має diffutils3.6, і тому він має.

На 3.5 це виглядає приблизно так:

введіть тут опис зображення

Перевірено:

diff --color -u \
  <(seq 6 | sed 's/$/ a/') \
  <(seq 8 | grep -Ev '^(2|3)$' | sed 's/$/ a/')

Мабуть, додано у комісії c0fa19fe92da71404f809aafb5f51cfd99b1bee2 (березень 2015 року).

Розріз на рівні слів

Як diff-highlight. Неможливо, здається, запит на функцію: https://lists.gnu.org/archive/html/diffutils-devel/2017-01/msg00001.html

Пов'язані теми:

ydiff чи це все-таки, дивіться нижче.

ydiff побічний рівень слів розл

https://github.com/ymattw/ydiff

Це Нірвана?

python3 -m pip install --user ydiff
diff -u a b | ydiff -s

Результат:

введіть тут опис зображення

Якщо рядки занадто вузькі (за замовчуванням 80 стовпців), розмістіть на екрані:

diff -u a b | ydiff -w 0 -s

Зміст тестових файлів:

а

1
2
3
4
5 the original line the original line the original line the original line
6
7
8
9
10
11
12
13
14
15 the original line the original line the original line the original line
16
17
18
19
20

б

1
2
3
4
5 the original line teh original line the original line the original line
6
7
8
9
10
11
12
13
14
15 the original line the original line the original line the origlnal line
16
17
18
19
20

ydiff Інтеграція Git

ydiff інтегрується з Git без необхідності будь-якої конфігурації.

Зсередини сховища git замість цього git diffви можете:

ydiff -s

і замість git log:

ydiff -ls

Дивіться також: Як я можу отримати бічний бік різниці, коли я роблю "git diff"?

Тестовано на Ubuntu 16.04, git 2.18.0, ydiff 1.1.


Ось документація.
Олексій

1
У цьому рядку списку розсилки: There is no word-highlighting, yet- якісь оновлення? Це те, до чого я прийшов до цього питання (я хочу - grep --colorподібний різний вихід).
i336_

@ i336_ жодних оновлень, на жаль, якщо я отримаю, я оновлю це питання. Пінг мені, якщо ти щось знайдеш.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

До речі git diff --colorтеж працює. Корисно при роботі над ssh.
Нагев

Різниця занадто велика? використанняdiff --color=always | less -R
inetphantom

69

І для тих випадків, коли yum install colordiffабо apt-get install colordiffне є можливим через якийсь шалений обмеження, що знаходиться поза вашим безпосереднім контролем, або ви просто божевільні , ви можете знову придумати колесо лінією sed:

sed 's/^-/\x1b[41m-/;s/^+/\x1b[42m+/;s/^@/\x1b[34m@/;s/$/\x1b[0m/'

Додайте, що в сценарії оболонки та трубі уніфікований різний вихід через нього.

Це робить маркери синього кольору блакитним кольором та виділяє нові / старі назви файлів та додає / видаляє лінії відповідно до зеленого та червоного фону. 1 І це зробить простір із заднім простором 2 зміни більш очевидними, ніж це може зробити colordiff.


1 Між іншим, причина виділення імен файлів такою ж, як і модифіковані рядки, полягає в тому, що для правильної розмежування назви файлів і модифікованих рядків потрібно правильно розібрати формат diff, що не є чимось вирішенням регулярного вираження. Виділення ними тих же робіт "досить добре" візуально і робить проблему банальною. Однак, є деякі цікаві тонкощі .

2 Але не вкладки. Мабуть, вкладки не встановлюють фон, принаймні в моєму xterm. Це все ж робить зміни вкладки проти простору трохи виділятися.


5
@Matt: Ось грубий підхід для Mac: sed "s/^-/`echo -e \"\x1b\"`[41m-/;s/^+/`echo -e \"\x1b\"`[42m+/;s/^@/`echo -e \"\x1b\"`[34m@/;s/$/`echo -e \"\x1b\"`[0m/"(хоча я сподіваюся, що є кращий спосіб).
втягування

1
Гм, це наче спрацювало ... дало 3 тире між кожним шматочком рожевий фон.
Метт Монтаг

Ручний нечитабельний, незрозумілий спосіб без можливості легкої зміни кольорів, наприклад.

1
Чувак, це приголомшливо! Шлях! Ось якась приємна сед-майстра.
fthinker

6
sed 's / ^ - / \ x1b [31m - /; s / ^ + / \ x1b [32m + /; s / ^ @ / \ x1b [34m @ /; s / $ / \ x1b [0m /' також виглядає чудово
Юра

16

Ви можете змінити конфігурацію підриву, щоб використовувати colordiff

~ / .subversion / config.diff

 ### Set diff-cmd to the absolute path of your 'diff' program.
 ###   This will override the compile-time default, which is to use
 ###   Subversion's internal diff implementation.
-# diff-cmd = diff_program (diff, gdiff, etc.)
+diff-cmd = colordiff

через: https://gist.github.com/westonruter/846524


svn: Не вдається запустити процес 'colordiff': ресурс тимчасово недоступний
niken

Ви встановили colordiff?
Azd325

Так, я також спробував
жорстко кодувати

idk спробуйте це superuser.com/questions/635995/…
Azd325

12

Кольорові, слово рівня diff Ouput

Ось що можна зробити із наведеним нижче сценарієм та розмежуванням розрізнень :

Кольоровий розл. Скріншот

#!/bin/sh -eu

# Use diff-highlight to show word-level differences

diff -U3 --minimal "$@" |
  sed 's/^-/\x1b[1;31m-/;s/^+/\x1b[1;32m+/;s/^@/\x1b[1;34m@/;s/$/\x1b[0m/' |
  diff-highlight

( Заслуговуйте на відповідь @ retracile за sedвиділення)


Як використовувати цей вихід у GVim?
Hemant Sharma

Для цього vimвикористовуйте плагін, наприклад, дифхар .
Том Хейл

10

Я використовую grc(Generic Colouriser), що дозволяє розфарбувати висновок кількох команд, у тому числі diff.

Це сценарій пітона, який можна обернути навколо будь-якої команди. Отже, замість виклику diff file1 file2, ви б викликали, grc diff file1 file2щоб побачити кольоровий вихід. Я diffзмушений grc diffбув зробити це легше.


Не працює в Windows з mingw / cygwin через fork()дзвінки, хоча, ймовірно, працює з WSL.
Габріель Дияволс

6

Ось ще одне рішення , яке викликає sedвставити відповідні послідовності ANSI рятуючи кольору , щоб показати +, -і @лінію в червоному, зелений і блакитний, відповідно.

diff -u old new | sed "s/^-/$(tput setaf 1)&/; s/^+/$(tput setaf 2)&/; s/^@/$(tput setaf 6)&/; s/$/$(tput sgr0)/"

На відміну від інших рішень цього питання, це рішення не чітко викладає послідовності відходу ANSI. Замість цього, він викликає команди tput setafта tput sgr0команди для генерації послідовностей запуску ANSI для встановлення відповідного кольору та скидання термінальних атрибутів відповідно.

Щоб переглянути доступні кольори для кожного аргументу tput setaf, використовуйте цю команду:

for i in {0..255}; do tput setaf $i; printf %4d $i; done; tput sgr0; echo

Ось як виглядає вихід:

введіть тут опис зображення

Ось докази того, що команди tput setafта tput sgr0команди генерують відповідні послідовності виходу ANSI:

$ tput setaf 1 | xxd -g1
00000000: 1b 5b 33 31 6d                                   .[31m
$ tput setaf 2 | xxd -g1
00000000: 1b 5b 33 32 6d                                   .[32m
$ tput setaf 6 | xxd -g1
00000000: 1b 5b 33 36 6d                                   .[36m
$ tput sgr0 | xxd -g1
00000000: 1b 28 42 1b 5b 6d                                .(B.[m

5

Оскільки wdiffприймає аргументи, що вказують рядок на початку та в кінці як вставок, так і видалень, ви можете використовувати послідовності кольорів ANSI як ці рядки:

wdiff -n -w $'\033[30;41m' -x $'\033[0m' -y $'\033[30;42m' -z $'\033[0m' file1 file2

Наприклад, це результат порівняння двох файлів CSV:

різний вихід CSV-файлів

Приклад із https://www.gnu.org/software/wdiff/manual/html_node/wdiff-Examples.html


1
colordiffТепер (1.0.16) розуміє wdiff, так що ви можете просто труба: wdiff -n f1 f2 | colordiff. wdiffповинні бути об'єднані в дифузори ...
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

3

Я б запропонував вам спробувати розмаїті настільки фантазії . Я використовую його під час своєї роботи, і це впевнено здається чудовим, як зараз. Він оснащений багатьма варіантами, і налаштувати діффайс так, як ви хочете, дуже просто.

Ви можете встановити його:

sudo npm install -g diff-so-fancy

або на Mac:

brew install diff-so-fancy

Після цього ви можете виділити свої відмінності так:

diff -u file1 file2 | diff-so-fancy


0

В останніх версіях git на Ubuntu ви можете ввімкнути різне підсвічування за допомогою:

sudo ln -s /usr/share/doc/git/contrib/diff-highlight/diff-highlight /usr/local/bin
sudo chmod a+x /usr/share/doc/git/contrib/diff-highlight/diff-highlight

А потім додайте це до свого .gitconfig:

[pager]
    log = diff-highlight | less
    show = diff-highlight | less
    diff = diff-highlight | less

Можливо, сценарій знаходиться десь в інших дистрибутивах, ви можете використовувати, locate diff-highlightщоб дізнатися, де.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.