Bagaimana cara menghapus baris dengan gema?

60

Saya tahu bahwa saya dapat menghapus tiga karakter terakhir dengan:

echo -ne '\b\b\b'

Tetapi bagaimana saya bisa menghapus satu baris penuh? Maksud saya, saya tidak ingin menggunakan:

echo -ne '\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b'

... dll ... untuk menghapus garis panjang.

LanceBaynes
sumber
2
Bagi mereka yang ingin terus menulis pada baris yang sama:, echo -ne "\033[2K" ; printf "\r"sekarang baris itu baik seperti baru, seolah-olah itu tidak pernah ditulis sebelumnya.
Hello World
2
Saya cukup yakin Anda bisa menggunakannya echo -ne "\e[2K\r". Namun ANSI lolos dari urutan FTW, toh.
Parthian Shot

Jawaban:

57

Anda dapat menggunakan \batau \runtuk memindahkan kursor kembali dan kemudian menimpa karakter yang dicetak dengan karakter baru. Perhatikan bahwa tidak ada \batau pun \rpenghapusan karakter yang dicetak. Itu hanya memindahkan kursor kembali. \bmemindahkan kursor kembali satu karakter dan \rmemindahkan kursor ke awal baris.

Contoh: keduanya

echo -e 'foooo\b\b\b\b\bbar'

dan

echo -e 'foooo\rbar'

akan dicetak:

baroo

Jika Anda ingin karakter dihapus maka Anda harus menggunakan solusi berikut:

echo -e 'fooooo\r     \rbar'

keluaran:

bar  

Kutipan dari man echo:

   If -e is in effect, the following sequences are recognized:

   \0NNN  the character whose ASCII code is NNN (octal)

   \\     backslash

   \a     alert (BEL)

   \b     backspace

   \c     produce no further output

   \f     form feed

   \n     new line

   \r     carriage return

   \t     horizontal tab

   \v     vertical tab

   NOTE: your shell may have its own version of echo, which usually super‐
   sedes the version described here.  Please refer to your  shell's  docu‐
   mentation for details about the options it supports.
lesmana
sumber
4
Ya, tapi echo -e 'fooooooooo\rbargema barooooooo.
Mat
1
Ya kamu benar. Perhatikan echo -e 'foooo\b\b\b\b\b\b\b\b\b\bbar'juga gema baroo.
lesmana
Sangat manis, bekerja dengan sempurna printf.
Michael-O
4
Jawaban yang sangat tidak akurat. Yang Kevin benar-benar lebih baik
Mike Aski
87

Anda sedang mencari pelarian terminal . Secara khusus, untuk menghapus dari posisi kursor ke awal baris:

echo -e "\033[1K"

Atau semua yang ada di telepon, terlepas dari posisi kursor:

echo -e "\033[2K"

Dan Anda dapat melakukan segala macam trik rapi lainnya dengan terminal lolos juga.

Kevin
sumber
6
Ini mengasumsikan terminal atau emulator yang kompatibel dengan VT100 (yang merupakan asumsi yang cukup aman akhir-akhir ini).
Keith Thompson
2
Jika Anda ingin menghapus sesuatu yang baru saja Anda gema, gema Anda sebelumnya harus memiliki tanda -n, atau Anda akan dikirim ke baris baru
djjeck
1
Jika Anda ingin menulis sesuatu yang lain, pada baris yang Anda hapus, tambahkan tanda -n pada gema di atas, atau Anda akan pergi ke baris baru setelah menghapusnya. Juga, tambahkan a ke string di atas, atau konten baru Anda tidak akan pergi ke awal baris itu.
Djjeck
-1 | -ekarena echoargumen tidak sesuai dengan POSIX + Saya tidak suka urutan escape. Lebih suka printfatau tput.
LinuxSecurityFreak
@Vastimil mengapa Anda membatalkan ini? OP tidak meminta jawaban yang Anda inginkan. Mungkin dia seharusnya mendahului -eparameter untuk echotidak sesuai dengan POSIX tetapi masih ...
souki
35

Jika Anda ingin menghapus garis, maka saya sarankan Anda menggunakan kombinasi carriage return yang orang sebutkan dan terminfo.

# terminfo clr_eol
ceol=$(tput el)
echo -ne "xyzzyxyzzy\r${ceol}foobar"

Ini akan menulis xyzzyxyzzy, kemudian kembali ke awal baris dan mengirim urutan "jelas ke ujung baris" ke terminal, kemudian menulis foobar. The -necho tidak menambahkan baris baru setelah foobar.

Arcege
sumber
4
Saya suka jenis pembuktian di masa depan dari solusi khusus ini - menggunakan tput mungkin berarti itu akan bekerja pada semua jenis terminal.
Amos Shapira
2
Lebih baik printf '%s\r%s%s' xyzzyxyzzy "$ceol" foobaruntuk portabilitas dan untuk menghindari memiliki konten $ceolmelalui \xekspansi.
Stéphane Chazelas
Jawaban terbaik jika hanya karena itu bekerja dengan garis panjang sewenang-wenang. Terima kasih!
Raphael
bekerja dengan sempurna. Tetapi jika saya mengubah ukuran layar terminal lebih kecil dari garis output, itu menjadi berantakan.
K.Sopheak
11

Anda secara eksplisit meminta echo, tetapi permintaan ini membuat Anda kecewa. Berikut ini pendekatan yang menggunakan printfperintah built bash dengan brace expansion:

printf 'fooooooooo' # 10 characters
printf '\r'; printf ' %0.s' {0..9} # 10 expansions of the space character
kojiro
sumber
1
sempurna! persis apa yang saya butuhkan
Omar S.
2
printf 'Status: started'; sleep 2s; printf '\ r'; printf 'Status: updated'; sleep 2s; printf '\ r';
Omar S.
4

Berikut ini contoh menggunakan echo no newline -n dan carriage return \r options.

bash menimpa jalur terminal

#!/bin/bash

CHECK_MARK="\033[0;32m\xE2\x9C\x94\033[0m"

echo -e "\n\e[4mDoing Things\e[0m"
echo -n "doing thing 1..."
sleep 1
echo -e "\\r${CHECK_MARK} thing 1 done"
Derek Soike
sumber
Tanda centang berfungsi bahkan di RHEL6. Bagus untuk suntingan estetika murni dari skrip saya
oneindelijk
1

Alih-alih echo -en "\r"Anda mungkin juga menemukan printf "\r"perintah sebagai berguna. Dengan cara ini Anda dapat memformat string. misalnya:

for sec in {1..100}; do printf "\r %04d" ${sec}; sleep 0.1; done

Saya biasanya melakukannya juga ketika beroperasi dengan parsing file lambat untuk menampilkan nama file yang sedang berlangsung tanpa membuat daftar

McPeppr
sumber
-1 | Mungkin Anda ingin secara sengaja membuat one-liner, tetapi itu sebenarnya hanya baik untuk pengujian. Saya akan menulis ulang dengan benar dengan baris baru.
LinuxSecurityFreak
0

Sebagai pertanyaan, hapus baris penuh

Saya telah menggunakan perintah di bawah ini dengan kombinasi echodan seduntuk menghapus baris

Setelah eksekusi, hasil perintah akan kosong. Sejak saat baris tidak akan diganti

perintah

echo  "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" | sed -r "s/.*//g"
Praveen Kumar BS
sumber
-1

Berikut adalah contoh penghitung waktu mundur yang saya gunakan:

i=10
while [ $i -gt 0 ]; 
do 
  printf "$i seconds remaining       " && printf '\r\033[1B'
  i=`expr $i - 1`
  sleep 1
  printf '\033[1A'
done
mikiemorales
sumber
-1 | Mungkin Anda ingin secara sengaja membuat one-liner, tetapi itu sebenarnya hanya baik untuk pengujian. Saya akan menulis ulang dengan benar dengan baris baru.
LinuxSecurityFreak
Kemudian, silakan lakukan dan tambahkan jawaban baru. Atau usulkan hasil edit jawaban saya.
mikiemorales