web-dev-qa-db-ja.com

なんらかのネガティブエコーを使用して、以前のエコーと同じ場所にコンソールで何かを印刷します

Bashでは、clearという名前のコマンドをキャストして、すべての画面コマンドをクリアできます。

echoを使用すると、画面上に何でも印刷できます。

私の単純なスクリプトでは、コマンドで行われていることの割合を出力する必要があることがよくあります。

だから私は何かをすることができました...

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

等々..

私が嫌いなのは、画面がパーセント更新でいっぱいになることです...

89%
90%
91%
...

私が欲しいのは、bashやphp echoでエコーできる特別な文字の組み合わせ(たとえば、「\ 033 [01; 31m」)があり、コンソールに「最後に印刷された文字を削除する」と伝える場合です。

次のようなものを使用してそうします:(phpの例)

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

画面に行をいっぱいにせずに、新しい文字列を前の文字列の正確な位置に印刷します

それ以外の場合は、常にbashおよびphpスクリプトを使用して、他の方法で同じことを行う方法を探します(少なくともdebian9コンソールとphp7で実際の実際の例を含めてください)

9
user3450548

これを行う一般的な方法は、1文字を消去するのではなく、改行(\r)を使用して行の先頭に戻ることです。

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

ただし、これは明確なものではないため、必要に応じて対処する必要があります。単純なオプションは、末尾にスペースを追加するか、出力を固定幅にします(例:printf "%2d%%\n" 1は先行スペースを提供します)。

画面の一部を移動してクリアできるターミナルエスケープ CSIシーケンス がありますが、それらはターミナルに依存します(ただし、実際にはVT100エスケープはどこでもサポートされています)。例えば

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

␛[3Dを使用して3文字を左に移動し、それらを上書きします(printf\eをサポートしている場合)。

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

現在の行の先頭に移動するには␛[0Eを使用し、行の末尾に移動するには␛[Kを使用します(端末がこれらのシーケンスをサポートしている場合)。

tput は、これらのシーケンスにアクセスする端末およびprintf- agnostic方法を提供します。

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

現在の端末に適切な文字シーケンスを使用して、カーソルを左に3回(cub 3)移動し、行の終わり(el)までクリアします。

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

カーソルを左端の列(hpa 0)に移動し、行の終わりまでクリアします。

man terminfo は、tputで使用する「機能名」を示します。

(上記の例の詳細の多くは、すべての出力が同じ行にあることを前提としています。これらは、さまざまなアプローチを説明するためだけに、絶対確実であるとは限りません。)

PHPスクリプトの同様の画面制御については、PECL ncurses 拡張機能を見ることができます。

24
Stephen Kitt