Cetak sesuatu di konsol di tempat yang sama dengan gema sebelumnya, dengan semacam gema negatif

9

Dalam bash, Anda dapat melemparkan perintah yang bernama clearuntuk menghapus semua perintah layar

Dan dengan echoAnda dapat mencetak apa pun yang Anda inginkan pada layar ..

Dalam skrip sederhana saya, saya sering perlu mencetak persentase dari apa yang dilakukan dengan perintah saya ..

Jadi saya bisa melakukan sesuatu seperti ..

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

dan seterusnya..

apa yang saya benci adalah mendapatkan layar yang penuh dengan persen pembaruan ...

89%
90%
91%
...

yang ingin saya pelajari adalah jika ada kombinasi karakter khusus (mis. "\ 033 [01; 31m") yang dapat digaungkan dengan bash atau php echo dan memberi tahu konsol "hapus karakter cetak sebelumnya yang sebelumnya .."

melakukannya dengan menggunakan sesuatu seperti: (contoh php)

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

Saya akan mendapatkan string baru dicetak pada posisi yang tepat dari yang sebelumnya tanpa layar penuh garis

Kalau tidak, saya mencari pendekatan untuk melakukan hal yang sama dengan cara lain selalu menggunakan skrip bash dan php (harap sertakan contoh kerja aktual setidaknya dengan konsol debian9 dan php7)

pengguna3450548
sumber

Jawaban:

24

Cara khas melakukan ini bukan untuk menghapus satu karakter, tetapi untuk kembali ke awal baris menggunakan carriage return ( \r):

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

Perhatikan bahwa ini tidak menghapus garis, jadi Anda harus mengurusnya jika perlu. Pilihan sederhana adalah menambahkan spasi ke ujung, atau membuat lebar tetap keluaran (mis. printf "%2d%%\n" 1Memberikan spasi utama).

Ada pelarian terminal yang akan memungkinkan Anda untuk bergerak dan membersihkan bagian layar, urutan CSI , tetapi mereka tergantung pada terminal (meskipun dalam praktiknya pelarian VT100 didukung di mana-mana sekarang). Sebagai contoh

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

gunakan ␛[3Duntuk memindahkan tiga karakter ke kiri, dan menulis di atasnya (dengan asumsi Anda printfmendukung \e);

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

digunakan ␛[0Euntuk pindah ke awal baris saat ini, dan ␛[Kuntuk menghapus ke akhir baris (dengan asumsi terminal Anda mendukung urutan itu).

tputmenyediakan cara terminal- dan printf-agnostik untuk mengakses urutan ini:

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

akan memindahkan kursor ke kiri tiga kali ( cub 3) dan menghapus ke akhir baris ( el), menggunakan urutan karakter apa pun yang sesuai untuk terminal saat ini;

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

akan memindahkan kursor ke kolom paling kiri ( hpa 0) dan menghapus ke akhir baris.

man terminfoakan memberi tahu Anda apa "nama kemampuan" untuk digunakan tput.

(Perhatikan bahwa banyak contoh-contoh di atas mengasumsikan bahwa semua output Anda berada pada baris yang sama. Mereka tidak seharusnya menjadi bukti yang bodoh, hanya untuk menggambarkan berbagai pendekatan.)

Untuk kontrol layar yang serupa dalam skrip PHP, Anda bisa melihat ncursesekstensi PECL .

Stephen Kitt
sumber
5
Satu biasanya dapat menggunakan tput cub 3untuk memindahkan cu rsor b ack oleh 3 kolom tanpa harus hardcode urutan (dan tput eluntuk e Rase yang l ine).
Stéphane Chazelas
1. \etidak portabel 2. juga tidak\e[0E
Steven Penny
Terima kasih @Steven, saya telah menyebutkan bahwa urutannya tergantung pada terminal tetapi saya telah menambahkan beberapa kualifikasi lagi.
Stephen Kitt
Satu bisa digunakan echuntuk penghapusan. Dan bergerak mundur dengan 3 posisi memiliki gotcha, dan dua kemungkinan optimasi yang cenderung digunakan oleh program layar penuh. Tetapi optimasi dan penghapusan sama-sama berlebihan untuk hal-hal terminal-line saat ini saja sederhana, ketika seseorang mengikuti saran itu untuk menggunakan specifier format lebar-tetap. Jangan lupa bahwa 100adalah 3 digit, dengan cara. (-:
JdeBP
Poin bagus @JdeBP, terima kasih. Setelah Anda mencapai 100%, saya harap Anda tidak lagi memerlukan pembaruan kemajuan ;-).
Stephen Kitt