Como canalizo a saída do diff colorida para menos?

37

Eu tenho usado git diff, que produz saída colorida. No entanto, agora acho que preciso usar o diff comum para alguma coisa, e está produzindo muito resultado difícil de ler devido à falta de cores. Como faço para o diff produzir uma saída legível e colorida? Idealmente, ao canalizá-lo para menos, para facilitar a revisão de arquivos grandes.

Benubird
fonte

Respostas:

32

diffnão pode produzir cores, você precisa de outro programa, como colordiffpara isso. As cores no terminal são impressas por meio de códigos de escape ANSI que menos não interpretam por padrão. Para lessmostrar corretamente as cores, você precisa da opção -r, ou melhor ainda, de -R:

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

De man less:

   -R or --RAW-CONTROL-CHARS
          Like -r, but only ANSI  "color"  escape  sequences  are
          output in "raw" form.  Unlike -r, the screen appearance
          is maintained correctly in most  cases.   ANSI  "color"
          escape sequences are sequences of the form:

               ESC [ ... m

          where  the  "..."  is  zero or more color specification
          characters For the purpose of keeping track  of  screen
          appearance,  ANSI color escape sequences are assumed to
          not move the cursor.  You  can  make  less  think  that
          characters  other  than  "m"  can end ANSI color escape
          sequences by setting the environment  variable  LESSAN‐
          SIENDCHARS  to  the  list of characters which can end a
          color escape sequence.  And you  can  make  less  think
          that characters other than the standard ones may appear
          between the ESC and the m by  setting  the  environment
          variable  LESSANSIMIDCHARS  to  the  list of characters
          which can appear.

Como alternativa, você pode usar o moreque exibirá as cores corretamente por padrão.


Se você não conseguir instalar programas externos, poderá obter a mesma saída usando uma abordagem mais manual:

diff a b | 
   perl -lpe 'if(/^</){$_ = "\e[1;31m$_\e[0m"} 
              elsif(/^>/){$_ = "\e[1;34m$_\e[0m"}'
terdon
fonte
1
E se alguém quiser visualizar a porcentagem dos dados exibidos, precisará usar less -RM +Gg: superuser.com/questions/64972/…
baptx
13

As outras respostas aqui podem estar desatualizadas. A partir do coreutils 3.5, de difffato, é possível produzir uma saída colorida que é desativada por padrão quando o stdout não é um console.

Na página do manual:

--color[=WHEN]
colorir a saída; WHENpode ser never, alwaysou auto(o padrão)

Forçar a saída de cores quando stdout é um tubo diff --color=always -- "$file1" "$file2" | less -Rdeve funcionar.

Kshitiz Sharma
fonte
Você também pode incluir alias diff='diff --color=always'em um arquivo .bashrcou .zshrc.
jftuga 19/09
1
Sim. Estou usandoalias diff='diff --side-by-side --left-column --color=always'
Kshitiz Sharma 19/09
Eu uso alias diff='/usr/bin/diff --color=always 'e, alias less='/usr/bin/less -r 'embora o diff seja inicialmente colorido nas primeiras páginas de menos mas em diffs longos, às vezes ele volta ao mono. Isso pode ocorrer em saltos que claramente não afetariam o diff, uma vez que sua saída é gerada apenas uma vez e não precisa ser saltada, mas de alguma forma menos perde o controle das cores.
NeilG 2/11
8

Para canalizar diff colorido para menos:

diff $file1 $file2 | colordiff | less -r

Para torná-lo mais legível, limitando-o a uma única tela:

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

E, para fazer com que menos não seja exibido se houver apenas uma tela com conteúdo:

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

O -F faz com que menos feche imediatamente se houver menos de uma tela com conteúdo, o canal para stderr ocorre porque quando menos fecha você perde a saída - ao canalizar para stderr, ele obtém saída mesmo que menos não seja exibido.

Uma maneira alternativa (e, na minha opinião, melhor) é usar apenas -X para evitar menos limpeza da tela:

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

Isso funciona bem para mim, mas pode ser específico para o bash. O colordiff não é um built-in, mas é facilmente instalado.

Benubird
fonte
2
O único comando que ele precisa éless -r
sendmoreinfo