Preservando saída de cores com corte

6

Usando o bash interativamente, estou tentando usar o corte para evitar que as linhas fiquem mais longas do que a largura do meu terminal. Mas ao usar um comando com saída colorida toda a cor é removida por corte. Por exemplo: ls -lG | cut -c 1-$COLUMNS .

Existe alguma maneira de cortar para preservar a formatação das cores?

    
por ken_o 13.01.2014 / 22:50

3 respostas

5

Você tem dois problemas aqui

  1. ls -G pára a saída em cores quando a saída não vai para um terminal (aqui para um pipe). O GNU ls precisa ser passado a uma opção --color=always e, para o BSD ls , é necessário definir o ambiente CLICOLOR_FORCE como um valor não vazio para que ele sempre imprima em cores.
  2. As cores são obtidas através da saída de sequências de escape que são uma sequência de caracteres como <ESC>[31m para o primeiro plano vermelho. Isso não tem largura quando exibido, mas no que se refere a cut , são 5 caracteres que contam até $COLUMNS .

    Portanto, você não pode usar cut aqui, pois você precisa ignorar essas sequências de escape no cálculo. Em vez disso, você poderia fazer algo como:

    esc=$'\e'
    CLICOLOR_FORCE=1 ls -l | sed "s/\(\(\($esc\[[0-9;]*m\)\{0,1\}.\{0,1\}\)\{$COLUMNS\}\).*/${esc}[m/"
    

    Lá, sed faz a contagem e adiciona um \e[m para reverter a cor para o padrão, caso ela tenha sido cortada no processo.

Alternativamente, você poderia dizer ao seu terminal para não embrulhar e fazer o corte com:

tput rmam

( tput smam para restaurar)

Você pode definir uma função como:

nowrap() {
  [ -t 1 ] && tput rmam
  "$@"; local ret="$?"
  [ -t 1 ] && tput smam
  return "$ret"
}
alias nowrap='nowrap '

(a parte alias para forçar a expansão de alias após nowrap ), para ser chamada como:

nowrap ls -l ...
    
por 13.01.2014 / 23:22
2

man ls :

   --color[=WHEN]
          colorize  the  output;  WHEN  can be 'never', 'auto', or 'always' (the
          default); more info below

Seu ls provavelmente está configurado para --color=auto , o que significa que ele só gera cores se estiver conectado diretamente a um terminal. (E não para outro comando como corte.)

Você pode usar --color=always , mas esteja ciente de que todo o material colorido funciona inserindo caracteres especiais (seqüências de escape) que ativam e desativam a cor. Se você cortar no meio de uma palavra colorida, removerá a seqüência "stop color" e a próxima linha também será colorida.

Talvez ls --color=always|less -RS faça o que você quer.

    
por 13.01.2014 / 22:59
1

Para falsificar a saída para um terminal e preservar a formatação de cor ls pode ser executado em um pseudo-terminal usando o comando (FreeBSD) script (ou ferramentas como ptymagic.c ).

script -q /dev/null ls -lG | tr -d '\r' | cut -c 1-$COLUMNS

ptymagic ls -lG | cut -c 1-$COLUMNS
    
por 14.01.2014 / 18:49