Pertanyaan Bagaimana cara menghapus dan mengganti baris terakhir di terminal menggunakan bash?


Saya ingin menerapkan bilah kemajuan yang menunjukkan detik yang berlalu dalam bash. Untuk ini, saya perlu menghapus baris terakhir yang ditampilkan di layar (perintah "hapus" menghapus semua layar, tetapi saya hanya perlu menghapus baris baris kemajuan dan menggantinya dengan informasi baru).

Hasil akhir akan terlihat seperti:

$ Elapsed time 5 seconds

Kemudian setelah 10 detik saya ingin mengganti kalimat ini (di posisi yang sama di layar) dengan:

$ Elapsed time 15 seconds

75
2018-03-05 16:06


asal


Jawaban:


gema carriage return dengan \ r

seq 1 1000000 | while read i; do echo -en "\r$i"; done

dari echo manusia:

-n     do not output the trailing newline
-e     enable interpretation of backslash escapes

\r     carriage return

97
2018-03-05 16:08



Pengembalian carriage dengan sendirinya hanya memindahkan kursor ke awal baris. Tidak masalah jika setiap baris output baru setidaknya sama dengan yang sebelumnya, tetapi jika baris baru lebih pendek, baris sebelumnya tidak akan sepenuhnya ditimpa, misalnya:

$ echo -e "abcdefghijklmnopqrstuvwxyz\r0123456789"
0123456789klmnopqrstuvwxyz

Untuk benar-benar menghapus garis untuk teks baru, Anda dapat menambahkan \033[K setelah \r:

$ echo -e "abcdefghijklmnopqrstuvwxyz\r\033[K0123456789"
0123456789

http://en.wikipedia.org/wiki/ANSI_escape_code


155
2017-07-21 10:06



Jawaban Derek Veit bekerja dengan baik selama panjang garis tidak pernah melebihi lebar terminal. Jika ini tidak terjadi, kode berikut akan mencegah keluaran sampah:

sebelum baris ditulis untuk pertama kalinya, lakukan

tput sc

yang menyimpan posisi kursor saat ini. Sekarang kapanpun Anda ingin mencetak baris Anda, gunakan

tput rc
tput ed
echo "your stuff here"

untuk pertama kembali ke posisi kursor yang disimpan, kemudian hapus layar dari kursor ke bawah, dan akhirnya tulis hasilnya.


16
2017-09-20 12:04



Metode \ 033 tidak bekerja untuk saya. Metode \ r bekerja tetapi sebenarnya tidak menghapus apa pun, cukup letakkan kursor di awal baris. Jadi jika string baru lebih pendek dari yang lama, Anda dapat melihat teks sisa di akhir baris. Pada akhirnya, tput adalah cara terbaik untuk pergi. Ini memiliki kegunaan lain selain hal kursor plus itu datang pra-instal di banyak distro Linux & BSD sehingga harus tersedia untuk sebagian besar pengguna bash.

#/bin/bash
tput sc # save cursor
printf "Something that I made up for this string"
sleep 1
tput rc;tput el # rc = restore cursor, el = erase to end of line
printf "Another message for testing"
sleep 1
tput rc;tput el
printf "Yet another one"
sleep 1
tput rc;tput el

Berikut ini adalah skrip hitungan mundur kecil untuk dimainkan:

#!/bin/bash
timeout () {
    tput sc
    time=$1; while [ $time -ge 0 ]; do
        tput rc; tput el
        printf "$2" $time
        ((time--))
        sleep 1
    done
    tput rc; tput ed;
}

timeout 10 "Self-destructing in %s"

10
2018-01-14 20:45



Gunakan karakter carriage return:

echo -e "Foo\rBar" # Will print "Bar"

4
2018-03-05 16:09



Jika output progresnya adalah multi-baris, atau skrip sudah akan mencetak karakter baris baru, Anda dapat melompat ke atas dengan sesuatu seperti:

printf "\033[5A"

yang akan membuat kursor melompat 5 baris ke atas. Kemudian Anda dapat menimpa apa pun yang Anda butuhkan.

Jika itu tidak berhasil, Anda bisa mencoba printf "\e[5A" atau echo -e "\033[5A", yang seharusnya memiliki efek yang sama.

Pada dasarnya, dengan escape sequence Anda dapat mengontrol hampir semua yang ada di layar.


2
2018-05-19 22:16



Cara paling sederhana adalah menggunakan \r karakter saya kira.

Kekurangannya adalah Anda tidak dapat memiliki garis lengkap, karena hanya membersihkan baris saat ini.

Contoh sederhana:

time=5
echo -n "Elapsed $time seconds"
sleep 10
time=15
echo -n "Elapsed $time seconds"

echo "\nDone"

-1
2018-03-05 16:13