Eu tenho algum script que produz saída com cores e preciso remover os códigos ANSI.
#!/bin/bash
exec > >(tee log) # redirect the output to a file but keep it on stdout
exec 2>&1
./somescript
A saída é (no arquivo de log):
java (pid 12321) is running...@[60G[@[0;32m OK @[0;39m]
Eu não sabia como colocar o caractere ESC aqui, então coloquei @
em seu lugar.
Eu mudei o script para:
#!/bin/bash
exec > >(tee log) # redirect the output to a file but keep it on stdout
exec 2>&1
./somescript | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
Mas agora ele me fornece (no arquivo de log):
java (pid 12321) is running...@[60G[ OK ]
Como também posso remover isso ' @[60G
?
Talvez haja uma maneira de desativar completamente a coloração de todo o script?
strip-ansi
: github.com/chalk/strip-ansi .Respostas:
Segundo a Wikipedia , o
[m|K]
nosed
comando que você está usando é especificamente projetado para lidar comm
(o comando de cor) eK
(a "parte de apagamento da linha de comando"). Seu script está tentando definir a posição absoluta do cursor como 60 (^[[60G
) para obter todos os OKs em uma linha, que suased
linha não cobre.(Devidamente,
[m|K]
provavelmente deveria ser(m|K)
ou[mK]
, porque você não está tentando corresponder a um caractere de pipe. Mas isso não é importante no momento.)Se você alternar a correspondência final em seu comando para
[mGK]
ou(m|G|K)
, poderá capturar essa sequência de controle extra.fonte
brew install gnu-sed
instalará uma versão capaz. Corra comgsed
.echo "$(tput setaf 1)foo$(tput sgr0) bar" | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" | cat -A
, entendo:foo^O bar$
então acho que alguns caracteres não foram removidos corretamente, certo? Você sabe como corrigir?setaf
suporte) exigem mais parâmetros do que apenas dois; meu regex suporta dois. Alterar a primeira?
saída*
deve ajudar. A manipulaçãosgr0
é possível, mas com base em uma pesquisa, ela provavelmente cresce fora do escopo desta resposta baseada em regex hacky.sed
para o tubo para retirar a "mudança de" caráter[38;5;45m
). Esta resposta alternativa funciona unix.stackexchange.com/a/55547/168277Não consegui resultados decentes com nenhuma das outras respostas, mas o seguinte funcionou para mim:
Se eu apenas removi o caractere de controle "^ [", ele deixou o restante dos dados de cores, por exemplo, "33m". Incluir o código de cores e "m" fez o truque. Estou intrigado com s / \ x1B // g não funciona porque \ x1B [31m certamente funciona com eco.
fonte
-E
vez de-r
para regex estendido. Mais pode ser encontrado aqui{1,3}
a{,3}
(caso contrário ele ainda estava pulando alguns controles), graças para a sua solução!sed -r "s/[[:cntrl:]]\[([0-9]{1,3};)*[0-9]{1,3}m//g"
IMHO, a maioria dessas respostas se esforça demais para restringir o que está dentro do código de escape. Como resultado, eles acabam perdendo códigos comuns como
[38;5;60m
(cor ANSI 60 de primeiro plano no modo de 256 cores).Eles também exigem a
-r
opção que permite extensões GNU . Estes não são necessários; eles apenas fazem o regex ler melhor.Aqui está uma resposta mais simples que lida com as fugas de 256 cores e funciona em sistemas com não-GNU
sed
:Isso irá capturar qualquer coisa que comece com
[
, tenha qualquer número de casas decimais e ponto-e-vírgula e termine com uma letra. Isso deve capturar qualquer uma das seqüências de escape ANSI comuns .Para diversão, aqui está uma solução maior e mais geral (mas minimamente testada) para todas as seqüências de escape ANSI concebíveis :
(e se você tiver o problema de SI do @ edi9999, adicione
| sed "s/\x0f//g"
até o final; isso funciona para qualquer caractere de controle substituindo0f
pelo hexadecimal do caractere indesejado)fonte
|
no sed,]
dentro de uma classe de caracteres no sed e'
em uma sequência de caracteres de citação única. Agora ele está trabalhando para mim em um caso de teste muito básico.Para Mac OSX ou BSD, use
fonte
-E
sinalizador para sed para ativar o regexp estendido.Eu também tive o problema de que, às vezes, o personagem SI aparecia.
Aconteceu, por exemplo, com esta entrada:
echo "$(tput setaf 1)foo$(tput sgr0) bar"
Aqui está uma maneira de também remover o caractere SI (shift in) (0x0f)
fonte
Hmm, não tenho certeza se isso funcionará para você, mas 'tr' irá 'remover' (excluir) os códigos de controle - tente:
fonte
rwxr-xr-x 1 tokra admin 22 Oct 18 14:21 [0m[01;36m/usr/local/opt/gradle[0m -> [01;34m../Cellar/gradle/4.2.1[0m/
Eu tive um problema parecido. Todas as soluções que encontrei funcionaram bem para os códigos de cores, mas não removeram os caracteres adicionados por
"$(tput sgr0)"
(redefinindo atributos).Tomando, por exemplo, a solução no comentário de davemyron, o comprimento da sequência resultante no exemplo abaixo é 9, não 6:
Para funcionar corretamente, o regex precisou ser estendido para corresponder também à sequência adicionada por
sgr0
("\E(B
"):fonte
Função muito mais simples no Bash puro para filtrar códigos ANSI comuns de um fluxo de texto:
Vejo:
fonte
tldr
. (Embora eu uso zsh por isso pode ser também por causa disso.)extglob
ou provavelmente também não entenderá a substituição de cadeias por completo.sed
mencionados aqui que funcionarão com o Zsh.A solução da @ jeff-bowman me ajudou a me livrar de ALGUNS códigos de cores. Adicionei outra pequena porção ao regex para remover um pouco mais:
fonte
Aqui está uma solução Bash pura.
Salve como
strip-escape-codes.sh
, torne executável e execute<command-producing-colorful-output> | ./strip-escape-codes.sh
.Observe que isso remove todos os códigos / seqüências de escape ANSI. Se você deseja descascar apenas cores, substitua
[a-zA-Z]
por"m"
.Bash> = 4.0:
Bash <4.0:
fonte
A idéia controversa seria reconfigurar as configurações do terminal para esse ambiente de processo para permitir que o processo saiba que o terminal não suporta cores.
Algo como
TERM=xterm-mono ./somescript
vem à minha mente. YMMV com seu sistema operacional específico e capacidade de seu script para entender as configurações de cores dos terminais.fonte
Isso funciona para mim:
fonte
somescript
é implementado. Pode ou não reconhecer que sua saída padrão é um tty. (As palavras infratores realmente codificam códigos de escape específicos do terminal no programa e quebram horrivelmente quando usadas em outros terminais ou em scripts).