如何使用bash删除并replaceterminal中的最后一行?
我想实现一个进度条,显示在bash中经过的秒数。 为此,我需要清除屏幕上显示的最后一行(命令“清除”将擦除所有屏幕,但是我只需要删除进度条的行并用新信息replace它)。
最终结果应该如下所示:
$ Elapsed time 5 seconds
然后10秒钟后,我想要replace这个句子(在屏幕上的相同位置):
$ Elapsed time 15 seconds
用\ r回车回车
seq 1 1000000 | while read i; do echo -en "\r$i"; done
来自男人的回声:
-n do not output the trailing newline -e enable interpretation of backslash escapes \r carriage return
回车本身只将光标移动到行首。 如果每一行新的输出至less与前一行一样长,但是如果新行较短,则前一行不会被完全覆盖,例如:
$ echo -e "abcdefghijklmnopqrstuvwxyz\r0123456789" 0123456789klmnopqrstuvwxyz
要真正清除新文本的行,可以在\r
:
$ echo -e "abcdefghijklmnopqrstuvwxyz\r\033[K0123456789" 0123456789
只要线路长度不超过terminal宽度,Derek Veit的答案就能正常工作。 如果不是这种情况,下面的代码将防止垃圾输出:
在第一次写行之前,请做
tput sc
保存当前的光标位置。 现在,只要你想打印你的线,使用
tput rc tput ed echo "your stuff here"
首先返回到保存的光标位置,然后从光标到底部清除屏幕,最后写入输出。
\ 033方法不适合我。 \ r方法可以工作,但实际上并没有擦除任何东西,只要将光标放在行首即可。 所以如果新的string比旧的string短,你可以在行尾看到剩余的文本。 最后,这是最好的select。 它除了光标外还有其他用途,加上它预装在许多Linux和BSD发行版中,所以它应该可用于大多数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
这里有一个倒计时脚本来玩:
#!/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"
使用回车符:
echo -e "Foo\rBar" # Will print "Bar"
如果进度输出是多行的,或者脚本已经打印了新的行字符,则可以用类似的方式跳转行:
printf "\033[5A"
这将使光标跳到5行。 那么你可以覆盖任何你需要的。
如果这不起作用,你可以尝试printf "\e[5A"
或echo -e "\033[5A"
,这应该有相同的效果。
基本上, 转义序列可以控制屏幕上的几乎所有东西。
最简单的方法是使用\r
字符我猜。
缺点是你不能有完整的行,因为它只清除当前行。
简单的例子:
time=5 echo -n "Elapsed $time seconds" sleep 10 time=15 echo -n "Elapsed $time seconds" echo "\nDone"