如何使用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 

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

只要线路长度不超过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"