Jak wydrukować różnicę kolorów?

18

Chciałem sformatować pliki Unix warunkowo, obecnie pracuję nad diffpoleceniem i chciałem wiedzieć, czy można sformatować tekst wyniku diffpolecenia.

Przykład:

Dopasowane wartości powinny być wyświetlane na zielono.
Niedopasowane wartości powinny być wyświetlane na czerwono.

Załóżmy, że mam dwa pliki file1i file2a moja komenda diff file1 file2.

Teraz chciałem, aby założenie, że dane wyjściowe zawierają 5 niezgodności, to te niezgodności powinny być wyświetlane w kolorze czerwonym. Jak to osiągnąć za pomocą unixa?

W skrócie „Zmień kolor na czerwony dla wyjścia polecenia diff dla wartości, które są niezgodne”

Mężczyzna
źródło
2
Możliwe powtórzenie tego
FloHimself 16.04.15
Terminy „dopasuj” i „mismach” są nieco mylące. W każdym razie istnieje opcja --color teraz w diff 3.4 i nowszych.
Gerry Lufwansa,

Odpowiedzi:

24

diff --color dodano opcję GNU diffutils 3.4 (2016-08-08)

Jest to domyślna diffimplementacja większości dystrybucji, która wkrótce ją otrzyma.

W wersji 3.5 wygląda to tak:

wprowadź opis zdjęcia tutaj

z:

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

Poprosiłem także o różnicę poziomów słów od diff-highlight: [Diffutils-devel] Dodaj flagę, aby uzyskać kolorowe wydruki, takie jak difit-h git | lists.gnu.org

Najwyraźniej dodano w zatwierdzeniu c0fa19fe92da71404f809aafb5f51cfd99b1bee2 (marzec 2015).

Ciro Santilli
źródło
1
Doskonały! Aby włączyć to domyślnie: alias diff='diff --color=auto'
Tom Hale,
1
Oto dokumentacja.
Alexey,
19

Jeśli masz dostęp do GNU diff, możesz użyć jego --X-group-formatopcji, aby uzyskać ten efekt bez żadnych dodatkowych narzędzi:

diff --old-group-format=$'\e[0;31m%<\e[0m' \
     --new-group-format=$'\e[0;31m%>\e[0m' \
     --unchanged-group-format=$'\e[0;32m%=\e[0m' \
     file1 file2

Korzysta z kodów ucieczki kolorów ANSI, aby uzyskać czerwony i zielony, z cytatem ANSI-C w powłoce, aby uzyskać dostęp do \eznaków ucieczki.

--old-group-formati --new-group-formatidentyfikuj niepasujące linie i wstaw je między czerwonymi i kolorowymi kodami resetowania, używając %<i %>, podczas gdy --unchanged-group-formatwstawia pasujące linie między zielonym i kodem resetowania.

Można również użyć--old-line-format (ETC), kosztem zbędnych kolorów ucieczek na każdej linii: --old-line-format=$'\e[0;31m%L\e[0m'.

Michael Homer
źródło
po uruchomieniu daje diff: 0653-821 niedozwolona opcja - - diff: 0653-821 niedozwolona opcja - o diff: 0653-821 niedozwolona opcja - d diff: 0653-821 niedozwolona opcja - - diff: 0653-821 niedozwolona opcja - g diff: 0653-821 niedozwolona opcja - o podobne błędy.
Aman
Przeszkadza, gdy uruchamiam twoje polecenia tak, jakby jedna linia na raz nie dawała nowej linii żadnego wyniku -bash-4.2 $ - new-group-format = $ '\ e [0; 31m%> \ e [0m' \ >
Aman
Czy mogę to skonfigurować domyślnie?
Eugen Konkov
@EugenKonkov Możesz ustawić alias lub funkcję w swojej powłoce, aby ją uruchomić diff.
Michael Homer,
Dało mi to trochę kłopotów z próbą uruchomienia go. Niezmienione rzeczy pojawiały się jako dodane ... poddał się i zainstalował Colordiff
Brian Peterson
9

Próbować colordiff file1 file2

Dostępność colordiff z dystrybucją Linux / BSD

Osoby korzystające z Debiana lub Ubuntu (lub dowolnego z ich pochodnych) mogą prawdopodobnie po prostu użyć „apt-get install colordiff” do pobrania i zainstalowania; colordiff jest także spakowany dla wielu innych dystrybucji i systemów operacyjnych Linux, UNIX i BSD.

(Cytat z http://www.colordiff.org/ )

modesto
źródło
1
Doskonały. Dla mnie diff --color=autobyły to tylko markery linii koloryzującej i pierwsza linia każdej +/ -sekcji. Pipowanie do less -SRułatwia przeglądanie.
Walf 18.10.18
4

Kolorowe wyjście na poziomie słowa diff

Oto, co możesz zrobić z poniższym skryptem i wyróżnieniem różnic :

Kolorowy zrzut ekranu różnicy

#!/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

( Podziękowania dla odpowiedzi @ retracile dla sedwyróżnienia)

Tom Hale
źródło
1

Powinieneś rzucić okiem na hlkomendę dostępną na github: git clone http://github.com/mbornet-hl/hl i na: http://www.flashnux.com/notes/page_000022_US.html

hlto komenda Linux napisana w C, zaprojektowana specjalnie do pokolorowania pliku tekstowego lub wyniku komendy. Możesz użyć do 42 kolorów jednocześnie i użyć pliku konfiguracyjnego, aby uprościć wiersze poleceń. Możesz pokolorować dane wyjściowe każdego polecenia, które można potokować do innego. A jeśli wiesz, jakie są wyrażenia regularne, korzystanie z nich będzie bardzo łatwe. Możesz użyć manstrony, aby zrozumieć, jak z niej korzystać.
hljest bardzo łatwy w użyciu i konfiguracji. Możesz nawet użyć skryptu hl_generic, aby pokolorować dane wyjściowe poleceń bez modyfikowania ich składni.
Możesz na przykład pokolorować dane wyjściowe diffpolecenia, wpisując zwykłe polecenie:

diff file1 file2

Jeśli potrzebujesz pomocy, po prostu wyślij mi e-mail.
Pozdrowienia.

mbornet
źródło
1

W tej chwili na Github jest naprawdę fajne narzędzie zbudowane z pythonem icdiff. Tworzy ładne kolorowe wydruki, które są również świadome „dotkliwości”. Używam go cały czas, więc warto to sprawdzić.

Joe Healey
źródło
1

jeśli masz zainstalowany vim, możesz to zrobić diff file1 file2 | vim -

Vim rozpozna format diff i nada mu odpowiednią kolorystykę. Myślnik na końcu ma pozwolić vimowi zaakceptować dane wejściowe z polecenia diff.

TrongBang
źródło
„view” (skrót tylko do odczytu do vima) lepiej nadaje się do tego celu.
Anupam Srivastava
1

Zainstaluj Generic Colouriser ( grc ) i:

grc diff file1 file2

Dostępne zarówno w systemie Linux, jak i MacOS.

Sohail Si
źródło
0

Albo możesz użyć

1.diff --color=auto file1 file2

2)colordiff file1 file2

3. Moje ulubione: git diff file1 file2zaimplementowane jak poniżej:

Obecnie używam i polecam to , używając git diff albo potokując jego wyjście colordiffza pomocą:

diff() { git diff --no-index "$1" "$2" | colordiff; }

himanshuxd
źródło
Też mi się podoba, git diff --no-indexale myślę, że pliki muszą być widoczne. (Przynajmniej nie działa dla mnie na podstawianie procesu bash)
Karl
@Karl Zastanów się, jak to rozdzielić, być może istnieje ustawienie terminalu, które robi to (lub) w inny sposób, aby było widoczne. Używam git diffod dawna, a plik jest dla mnie możliwy do zobaczenia, w przeciwnym razie nie przydałoby się, żebym zrobił to dobrze.
himanshuxd
2
Być może nie byłem jasny, bardzo jasny. Jako (głupi) przykład to działa dla mnie, diff --color <(ls | head -n+3) <(ls | tail -n +5)ale nie z git diff. Trzeba przyznać, że nie jest to zwykły przypadek ani zbyt trudny do obejścia.
Karl
0

Tylko uwaga: aby uzyskać wyjście „side-by-side” potrzebujesz ”--color = always”. Możesz także podzielić go na mniejsze i zachować kolorowe wydruki:

diff -y --color=always file1 file2 | less -R

I jeszcze jedna wskazówka: postaraj się zachować przełącznik „--color = always” na końcu. Powód? Z dmesg z util-linux 2.27.1:

dmesg --human --color=always | less -R    # works
dmesg --color=always --human | less -R    # doesn't work
Gus
źródło
0

Ten skrypt używa standardowej wersji diff wcześniejszej niż 3.4 (powinien działać z każdą wersją diff) i koloruje dane wyjściowe bez zmiany formatu wyjściowego w jakikolwiek sposób. Działa z najnowszą wersją RHEL (wersja 7.5), która ma wersję GNU diff 3.3. Po prostu umieść go w katalogu ~ / bin lub w dowolnym innym miejscu na swojej ścieżce (sugeruję nazywanie go „cdiff”).

#!/bin/bash
file1color="$(tput setaf 1)"
file2color="$(tput setaf 2)"
sepcolor="$(tput setaf 6)"
reset="$(tput sgr0)"
diff $* |sed -e "s/^\\(<.*\$\\)/$file1color\\1$reset/;s/^\\(>.*\$\\)/$file2color\\1$reset/;s/^\\(---\$\\)/$sepcolor\\1$reset/"
Beam Davis
źródło
0

Różnica kolorów na poziomie znaków: zainstaluj ccdiff

ccdiff -r /usr/share/dict/words /tmp/new-dict

Wyjście ccdiff

morela
źródło