Imprimer quelque chose dans la console au même endroit que l'écho précédent, avec une sorte d'écho négatif


9

Dans bash, vous pouvez lancer une commande nommée clearpour effacer toutes les commandes d'écran.

Et avec echovous, vous pouvez imprimer ce que vous voulez à l'écran.

Dans mes scripts simples, j'ai souvent besoin d'imprimer un pourcentage de ce qui se fait avec mes commandes.

Donc je pourrais faire quelque chose comme ..

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

etc..

ce que je déteste, c'est que l'écran soit plein de mises à jour en pourcentage ...

89%
90%
91%
...

ce que j'aimerais, c'est apprendre s'il y a une combinaison de caractères spéciaux (par exemple "\ 033 [01; 31m") qui pourrait être répercutée avec bash ou php echo et dire à la console "supprimer le dernier caractère imprimé précédent .."

le faire en utilisant quelque chose comme: (exemple php)

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

J'obtiendrais la nouvelle chaîne imprimée à la position exacte de la précédente sans avoir l'écran plein de lignes

Sinon, je cherche une approche pour faire la même chose à d'autres égards en utilisant toujours des scripts bash et php (veuillez inclure des exemples de travail réels au moins avec une console debian9 et php7)

Réponses:


24

La manière typique de procéder n'est pas d'effacer un seul caractère, mais de revenir au début de la ligne en utilisant un retour chariot ( \r):

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

Notez que cela n'efface pas la ligne, vous devez donc vous en occuper si nécessaire. Les options simples consistent à ajouter des espaces à la fin ou à rendre la sortie de largeur fixe (par exemple, printf "%2d%%\n" 1donne un espace de tête).

Il existe des échappements de terminal qui vous permettront de vous déplacer et d'effacer des parties de l'écran, les séquences CSI , mais elles dépendent du terminal (bien qu'en pratique les échappements VT100 soient pris en charge partout maintenant). Par exemple

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

utilise ␛[3Dpour déplacer trois caractères vers la gauche et les écrase (en supposant vos printfsupports \e);

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

permet ␛[0Ede se déplacer au début de la ligne en cours et ␛[Kd'effacer jusqu'à la fin de la ligne (en supposant que votre terminal prend en charge ces séquences).

tputfournit un moyen terminal et printf-agnostique d'accéder à ces séquences:

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

déplacera le curseur vers la gauche trois fois ( cub 3) et effacera jusqu'à la fin de la ligne ( el), en utilisant la séquence de caractères appropriée pour le terminal actuel;

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

déplacera le curseur dans la colonne la plus à gauche ( hpa 0) et effacera jusqu'à la fin de la ligne.

man terminfovous dira avec quel «nom de capacité» utiliser tput.

(Notez que la plupart des spécificités des exemples ci-dessus supposent que toutes vos sorties sont sur la même ligne. Elles ne sont pas censées être infaillibles, uniquement pour illustrer diverses approches.)

Pour un contrôle d'écran similaire dans les scripts PHP, vous pouvez consulter l' ncursesextension PECL .


5
On peut habituellement utiliser tput cub 3pour déplacer le cu rsor b par 3 colonnes ack sans avoir à coder la séquence (et tput elà e raser le l ine).
Stéphane Chazelas

1. \en'est pas portable 2. ni l'un ni l'autre\e[0E
Steven Penny

Merci @Steven, j'avais mentionné que les séquences dépendaient du terminal mais j'ai ajouté quelques qualificatifs supplémentaires.
Stephen Kitt

On pourrait utiliser echpour l'effacement. Et reculer de 3 positions a un piège, et deux optimisations possibles que les programmes plein écran ont tendance à utiliser. Mais les optimisations et l'effacement sont exagérés pour les simples trucs de terminal de ligne courante uniquement, quand on suit ce conseil pour utiliser un spécificateur de format à largeur fixe. N'oubliez pas que cela 100fait 3 chiffres, soit dit en passant. (-:
JdeBP

Bons points @JdeBP, merci. Une fois que vous avez atteint 100%, j'espère que vous n'aurez plus besoin de mises à jour de progression ;-).
Stephen Kitt
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.