Imprima algo no console no mesmo local do eco anterior, com uma espécie de eco negativo

9

No bash, você pode converter um comando nomeado clearpara limpar todos os comandos da tela.

E echovocê pode imprimir o que quiser na tela.

Nos meus scripts simples, geralmente tenho a necessidade de imprimir uma porcentagem do que está sendo feito com meus comandos.

Então eu poderia fazer algo como ..

echo "89%"
echo "90%"
echo "91%"

e assim por diante..

o que eu odeio é ter a tela cheia de atualizações percentuais ...

89%
90%
91%
...

o que eu gostaria de saber é se existe uma combinação especial de caracteres (por exemplo, "\ 033 [01; 31m") que pode ser repetida com bash ou php echo e informa ao console "remova o último caractere impresso anterior .."

fazendo isso usando algo como: (exemplo php)

echo str_repeat($neg_character, strlen($last_percentage_update_string));
echo $new_percentage_update_string;

Gostaria que a nova string fosse impressa na posição exata da anterior sem ter a tela cheia de linhas

Caso contrário, procuro uma abordagem para fazer o mesmo de outras maneiras, sempre usando scripts bash e php (por favor, inclua exemplos de trabalho reais pelo menos com um console debian9 e php7)

user3450548
fonte

Respostas:

24

A maneira típica de fazer isso não é apagar um único caractere, mas voltar ao início da linha usando um retorno de carro ( \r):

printf "89%%"; sleep 1; printf "\r90%%\n"

Observe que isso não limpa a linha; portanto, você precisa cuidar disso, se necessário. Opções simples são adicionar espaços ao final ou tornar a saída de largura fixa (por exemplo, printf "%2d%%\n" 1fornece um espaço inicial).

Existem escapes de terminal que permitirão que você se mova e limpe partes da tela, as seqüências CSI , mas elas dependem do terminal (embora, na prática, escapes do VT100 sejam suportados em todos os lugares agora). Por exemplo

printf "89%%"; sleep 1; printf "\e[3D90%%\n"

usa ␛[3Dpara mover três caracteres para a esquerda e escreve sobre eles (assumindo seus printfapoios \e);

printf "89%% hello"; sleep 1; printf "\e[0E\e[K90%%\n"

usa ␛[0Epara ir para o início da linha atual e ␛[Klimpar para o final da linha (supondo que o seu terminal suporte essas seqüências).

tputfornece uma maneira terminal e printfmagnética de acessar essas seqüências:

printf "89%%"; sleep 1; tput cub 3; tput el; printf "90%%\n"

moverá o cursor para a esquerda três vezes ( cub 3) e limpará até o final da linha ( el), usando a sequência de caracteres apropriada para o terminal atual;

printf "89%% hello"; sleep 1; tput hpa 0; tput el; printf "90%%\n"

moverá o cursor para a coluna mais à esquerda ( hpa 0) e limpará até o final da linha.

man terminfolhe dirá com que "nome da capacidade" usar tput.

(Observe que muitas das especificidades dos exemplos acima assumem que toda a sua saída está na mesma linha. Elas não devem ser à prova de idiotas, apenas para ilustrar várias abordagens.)

Para controle de tela semelhante em scripts PHP, você pode olhar para a ncursesextensão PECL .

Stephen Kitt
fonte
5
Geralmente pode-se utilizar tput cub 3para mover o cu rsor b ACK por 3 colunas, sem ter de codificar a sequência (e tput elpara e rase o l ine).
Stéphane Chazelas
1. \enão é portátil 2. nem é\e[0E
Steven Penny
Obrigado @Steven, eu mencionei que as seqüências eram dependentes do terminal, mas adicionei mais alguns qualificadores.
Stephen Kitt
Pode-se usar echpara apagar. E retroceder em três posições tem uma pegadinha e duas possíveis otimizações que os programas em tela cheia tendem a usar. Mas otimizações e apagamento são um exagero para coisas simples de terminal somente de linha de corrente, quando se segue esse conselho para usar um especificador de formato de largura fixa. A 100propósito, não esqueça que são 3 dígitos. (-:
JdeBP 23/08
Bons pontos @JdeBP, obrigado. Depois de atingir 100%, espero que você não precise mais de atualizações de progresso ;-).
Stephen Kitt