É possível alterar as cores das fontes no terminal, sem afetar o formato de preenchimento “% * s” do printf?

7

Eu tenho uma função em um script bash: message_offset , que é usado para imprimir o status de um script bash. ou seja, você chamaria de passar uma mensagem para ele e um status, como este

message_offset "install font library" "[   OK   ]" 

e imprimiria no terminal onde o formato printf %*s é usado para sempre definir o caractere mais à direita de [ OK ] em 80 colunas de largura por exemplo. saída seria

install font library                              [   OK   ]
update configuration file on server               [   ERR  ]
                                                           ^
                                                           |
                                                      always
                                                        at 80

Se echo foi usado, a saída ficaria assim

install font library                 [   OK   ]
update configuration file on server               [   ERR  ]

código:

#!/usr/bin/env bash

function message_offset() {

    local message="$1"
    local status="$2"

    # compensate for the message length by reducing the offset 
    # by the length of the message, 
    (( offset = 80 - ${#message} ))

    # add a $(tput sgr0) to the end to "exit attributes" whether a color was
    # set or not
    printf "%s%*s%s" "${message}" 80 "$status" "$(tput sgr0)"

}

tudo isso funciona ok, até eu tentar usar tput para adicionar algumas seqüências de cores na string, ou seja, para fazer "[ERR]" vermelho.
Parece que a formatação printf "%*s" está contando as seqüências de caracteres tput quando sua configuração do deslocamento, por isso, se eu chamar a função como esta

message_offset "update configuration file on server"  "$(tput setaf 1)[   ERR  ]"

a saída será parecida com:

install font library                              [   OK   ]
update configuration file on server          [   ERR  ]

porque printf "%*s" está dizendo hey essa string tem todos os caracteres "[ ERR ]" , mais os caracteres "$(tput setaf 1) , mas obviamente os caracteres "$(tput setaf 1) não são impressos, portanto, na verdade, não afeta o preenchimento. > Existe uma maneira de adicionar cores às mensagens de "status" e também usar as seqüências de cores do estilo tput ?

    
por the_velour_fog 19.03.2017 / 09:04

2 respostas

8

Você está tornando isso muito mais complicado do que deveria ser. Você pode manipular o alinhamento com $message e não se importar com a largura das sequências ANSI:

#! /usr/bin/env bash

message() {
    [ x"$2" = xOK ] && color=2 || color=1
    let offset=$(tput cols)-4-${#2}
    printf "%-*s[ %s%s%s ]\n" $offset "$1" "$(tput setaf "$color")"  "$2" "$(tput sgr0)"
}  

message "install font library" "OK"
message "update configuration file on server" "ERR"

Editar: Por favor, note que a maioria das implementações printf(1) não lidam bem com cálculos de comprimentos para conjuntos de caracteres multibyte. Portanto, se você quiser imprimir mensagens com caracteres acentuados em UTF-8, talvez seja necessário uma abordagem diferente. encolher de ombros

    
por 19.03.2017 / 10:05
1

uma abordagem fácil é colorir tudo após ter sido alinhado

Em poucas palavras, você precisa

  • uma função (ou melhor, um script externo) para colorir uma string com cores (por exemplo, usando s,$regex,$color$&$resetcolor,gi

  • do perl
  • e você chama depois da impressão. códigos de escape de cores não alteram o alinhamento dessa maneira.

por exemplo: digamos que você criou um script chamado "colorize" que aceita argumentos de cores, seguido por expressões regulares a serem coloridas com essa cor: por exemplo, colorize -blue 'regex1' -green 'regex2'     você chama quando necessário:

 { code
   that
  formats and display things
 } | colorize -red 'ERR' -green 'OK'

Ter isso como um script por si só permite que você o use em qualquer lugar, por exemplo:

 df -h | colorize -red '[890].%'
    
por 20.03.2017 / 10:29