¿Cómo colorear diff en la línea de comando?

504

Cuando tengo un diff, ¿cómo puedo colorearlo para que se vea bien? Lo quiero para la línea de comandos, así que no hay soluciones GUI.

daniel kullmann
fuente
66
¿Algún sistema operativo / shell en particular?
Rowland Shaw
44
Prueba github.com/walles/riff . Como una ventaja adicional, resalta qué partes de las líneas cambiaron.
Johan Walles

Respuestas:

608

Las páginas de manual para diffsugerir no hay solución para la coloración desde dentro de sí mismo. Por favor considere usar colordiff. Es un contenedor diffque produce la misma salida que diff, excepto que aumenta la salida usando resaltado de sintaxis coloreada para aumentar la legibilidad:

diff old new | colordiff

o solo:

colordiff old new

Instalación:

  • Ubuntu / Debian: sudo apt-get install colordiff
  • OS X: brew install colordiffoport install colordiff
kaji
fuente
45
Acabo de encontrar eso yo mismo :-). Se puede canalizar a menos mediante el uso less -R, que muestra las secuencias de escape para los colores correctamente.
daniel kullmann
34
Solo puedo usar la sintaxis: colordiff file1 file2
Felipe Alvarez
3
Por desgracia, no funciona para la salida de lado a lado ( -yopción para habilitar) ☹ La vimdiffsugerencia a continuación probablemente sea una mejor manera
Hi-Angel
8
colordifffunciona bien svn diff | colordiff(es decir, en situaciones en las que solo tiene la diferencia, no los dos archivos que se difunden).
Cornstalks
8
Como una actualización del comentario de @ Hi-Angel: el colordiff se ha actualizado y ahora incluye -ysoporte de lado a lado ( ).
Bailey Parker
333

Use Vim :

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

O mejor aún, VimDiff (o vim -d, que es más corto de escribir) mostrará diferencias entre dos, tres o cuatro archivos uno al lado del otro.

Ejemplos:

vim -d /path/to/[ab]

vimdiff file1 file2 file3 file4
Johnsyweb
fuente
77
@Jichao: prefiero aprender los comandos en lugar de alejarlos. De esa manera, puedo usarlos en cualquier lugar, incluso cuando mis archivos de puntos no están disponibles.
Johnsyweb
1
@AquariusPower: ctrl-cy ctrl-xtiene otros usos en Vim. ctrl-qEs capturado por muchas terminales. Vea Escribir y dejar de fumar para encontrar la forma que mejor se adapte a sus necesidades.
Johnsyweb
1
Primero, ¿qué tipo de caparazón es este? zsh? No reconozco =(...)constructo. En segundo lugar, lo tenía diff -ur a ben mente.
x-yuri
1
Esta solución es mejor que la respuesta aceptada, ya que no requiere que tenga derechos de administrador del sistema e instale ninguna herramienta adicional
amanzoor
173

En realidad, parece haber otra opción (que solo noté recientemente, cuando me encontré con el problema descrito anteriormente):

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

Si tiene Git (que de todos modos ya podría estar usando), podrá usarlo para comparar, incluso si los archivos en sí no están bajo el control de versiones. Si no está habilitado para usted de manera predeterminada, habilitar el soporte de color aquí parece ser considerablemente más fácil que algunas de las soluciones alternativas mencionadas anteriormente.

Lars Baehren
fuente
19
Esto es bueno, pero lamentablemente esto no funciona cuando las entradas son tuberías. Por ejemplo, comparar archivos binarios a través de git diff <(xxd file1) <(xxd filed)no funciona.
Michael Anderson
8
Curiosamente, al menos uno de los archivos tiene que estar 'fuera del repositorio actual', según git help diff. Entonces, si tu git diff está vacío, intenta cdsalir de donde estás.
Mala solicitud
77
Para habilitar colores para git diff:git config color.diff auto
JPor qué el
2
súper simple y rápido
EE33
31
Si ambos archivos están dentro del repositorio actual, use git diff --no-indexpara comparar dos archivos.
Olivier 'Ölbaum' Scherler
95

diff --color La opción se agregó a GNU diffutils 3.4 (2016-08-08)

Esta es la diffimplementación predeterminada en la mayoría de las distribuciones, que pronto la obtendrá.

Ubuntu 18.04 tiene diffutils3.6 y por lo tanto lo tiene.

En 3.5 se ve así:

ingrese la descripción de la imagen aquí

Probado:

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

Aparentemente agregado en commit c0fa19fe92da71404f809aafb5f51cfd99b1bee2 (Mar 2015).

Diferencia de nivel de palabra

Al igual diff-highlight. Parece que no es posible, solicitud de función: https://lists.gnu.org/archive/html/diffutils-devel/2017-01/msg00001.html

Hilos relacionados:

ydiff lo hace sin embargo, ver más abajo.

ydiff nivel de palabra de lado a lado diff

https://github.com/ymattw/ydiff

¿Es este el nirvana?

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

Salir:

ingrese la descripción de la imagen aquí

Si las líneas son demasiado estrechas (80 columnas predeterminadas), ajuste a la pantalla con:

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

Contenido de los archivos de prueba:

una

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

si

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 Integración Git

ydiff se integra con Git sin ninguna configuración requerida.

Desde el interior de un repositorio de git, en lugar de git diff, puedes hacer solo:

ydiff -s

y en lugar de git log:

ydiff -ls

Ver también: ¿Cómo puedo obtener una diferencia de lado a lado cuando hago "git diff"?

Probado en Ubuntu 16.04, git 2.18.0, ydiff 1.1.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
Aquí está la documentación.
Alexey
1
En ese hilo de la lista de correo: There is no word-highlighting, yet- ¿alguna actualización? Esto es para lo que llegué a esta pregunta (quiero una grep --colorsalida diferencial similar).
i336_
@ i336_ desafortunadamente, si recibo alguna, actualizaré la pregunta. Hazme un ping si encuentras algo.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Por cierto git diff --colorfunciona también. Útil cuando se trabaja sobre ssh.
Nagev
Diferencia demasiado grande? usodiff --color=always | less -R
inetphantom
69

Y para aquellas ocasiones en las que a yum install colordiffo an apt-get install colordiffno es una opción debido a alguna limitación insana más allá de su control inmediato, o simplemente se siente loco , puede reinventar la rueda con una línea de sed:

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

Lance eso en un script de shell y canalice la salida diff unificada a través de él.

Hace que los marcadores de trozos sean azules y resalta nombres de archivo nuevos / antiguos y líneas agregadas / eliminadas en fondo verde y rojo, respectivamente. 1 Y hará que los cambios en el espacio posterior 2 sean más evidentes que el colordiff.


1 Incidentalmente, la razón para resaltar los nombres de archivo de la misma manera que las líneas modificadas es que para diferenciar correctamente los nombres de archivo y las líneas modificadas se requiere analizar correctamente el formato diff, que no es algo que se deba abordar con una expresión regular. Destacarlos de la misma manera funciona "suficientemente bien" visualmente y hace que el problema sea trivial. Dicho esto, hay algunas sutilezas interesantes .

2 Pero no pestañas finales. Aparentemente, las pestañas no tienen su fondo establecido, al menos en mi xterm. Sin embargo, hace que los cambios de tabulación vs espacio se destaquen un poco.

retroceder
fuente
55
@Matt: Aquí hay un enfoque de fuerza bruta para una Mac: sed "s/^-/`echo -e \"\x1b\"`[41m-/;s/^+/`echo -e \"\x1b\"`[42m+/;s/^@/`echo -e \"\x1b\"`[34m@/;s/$/`echo -e \"\x1b\"`[0m/"(aunque espero que haya una mejor manera).
retracta el
1
Hmm, funcionó ... dio a los 3 guiones entre cada trozo un fondo rosa.
Matt Montag el
Manual de forma ilegible, imposible de mantener sin una opción para cambiar fácilmente los colores, por ejemplo.
1
Amigo, esto es increíble! ¡Camino a seguir! Esa es una buena magia sed.
fthinker
66
sed 's / ^ - / \ x1b [31m - /; s / ^ + / \ x1b [32m + /; s / ^ @ / \ x1b [34m @ /; s / $ / \ x1b [0m /' también se ve muy bien
Yura
16

Puede cambiar la configuración de subversion para usar 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

vía: https://gist.github.com/westonruter/846524

Azd325
fuente
svn: No se puede iniciar el proceso 'colordiff': recurso temporalmente no disponible
niken
¿Instalaste colordiff?
Azd325
Sí, traté de codificar el camino también (correr en cygwin)
niken
idk intento podría esto superuser.com/questions/635995/...
Azd325
12

Color, salida de nivel de palabra diff

Esto es lo que puede hacer con el script a continuación y el resaltado de diferencias :

Captura de pantalla de color diff

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

(Crédito a la respuesta de @ retracile para el sedresaltado)

Tom Hale
fuente
¿Cómo uso esta salida en GVim?
Hemant Sharma
Para vim, use un complemento, por ejemplo, diffchar .
Tom Hale
10

Yo uso grc(Colouriser genérico), que le permite colorear la salida de una serie de comandos incluidos diff.

Es un script de Python que se puede envolver alrededor de cualquier comando. Entonces, en lugar de invocar diff file1 file2, invocaría grc diff file1 file2para ver la salida coloreada. He alias diffpara grc diffque sea más fácil.

dogbane
fuente
No funciona en Windows con mingw / cygwin debido a fork()llamadas, aunque es probable que funcione con WSL.
Gabriel Devillers
6

Aquí es otra solución que invoca sedpara insertar las secuencias de escape ANSI apropiados para los colores para mostrar los +, -y @líneas en rojo, verde, y cian, respectivamente.

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

A diferencia de las otras soluciones a esta pregunta, esta solución no explica explícitamente las secuencias de escape ANSI. En su lugar, invoca los comandos tput setafy tput sgr0para generar las secuencias de escape ANSI para establecer un color apropiado y restablecer los atributos del terminal, respectivamente.

Para ver los colores disponibles para cada argumento tput setaf, use este comando:

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

Así es como se ve la salida:

ingrese la descripción de la imagen aquí

Aquí está la evidencia de que los comandos tput setafy tput sgr0generan las secuencias de escape ANSI apropiadas:

$ 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
Susam Pal
fuente
5

Como wdiffacepta argumentos que especifican la cadena al principio y al final de ambas inserciones y eliminaciones, puede usar secuencias de color ANSI como esas cadenas:

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

Por ejemplo, este es el resultado de comparar dos archivos CSV:

salida diff de archivos CSV

Ejemplo de https://www.gnu.org/software/wdiff/manual/html_node/wdiff-Examples.html

jcomeau_ictx
fuente
1
colordiffahora (1.0.16) comprende wdiff, por lo que puede también acaba de tubería: wdiff -n f1 f2 | colordiff. wdiffdebería fusionarse en diffutils ...
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
3

Te sugiero que pruebes diff-so-fancy . Lo uso durante mi trabajo y seguro que parece genial a partir de ahora. Viene con muchas opciones y es muy fácil configurar sus diferencias de la manera que desee.

Puedes instalarlo de la siguiente manera:

sudo npm install -g diff-so-fancy

o en Mac:

brew install diff-so-fancy

Luego, puede resaltar sus diferencias de esta manera:

diff -u file1 file2 | diff-so-fancy
Naveen
fuente
1

Con el comando bat :

diff file1 file2 | bat -l diff
Jian Weihang
fuente
0

En versiones recientes de git en Ubuntu, puede habilitar el resaltado de diferencias con:

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

Y luego agregando esto a su .gitconfig:

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

Es posible que el script se encuentre en otro lugar en otras distribuciones, puede usar locate diff-highlightpara averiguar dónde.

nada101
fuente
0

Diferencia de color a nivel de caracteres: instalar ccdiff

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

Salida de ccdiff

albaricoque
fuente