bash脚本,擦除前一行?

时间:2011-05-02 19:18:44

标签: bash

在许多Linux程序中,例如curl,wget和任何带有进度表的程序,他们都会在每一定时间内不断更新底线。我如何在bash脚本中执行此操作?我现在能做的就是回应一条新线,这不是我想要的,因为它会积累起来。我确实遇到过一些提到“tput cup 0 0”的东西,但我尝试了它,它有点古怪。什么是最好的方式?

7 个答案:

答案 0 :(得分:33)

{
  for pc in $(seq 1 100); do
    echo -ne "$pc%\033[0K\r"
    usleep 100000
  done
  echo
}

“\ 033 [0K”将删除到该行的末尾 - 如果您的进度线在某些时候变短,尽管这可能不是您的目的所必需的。

“\ r”将光标移动到当前行的开头

-n on echo将阻止光标前进到下一行

答案 1 :(得分:11)

您也可以使用tput cuu1;tput el(或printf '\e[A\e[K')将光标向上移动一行并删除该行:

for i in {1..100};do echo $i;sleep 1;tput cuu1;tput el;done

答案 2 :(得分:10)

linuts'代码示例的小变化,将光标移动到开头,但不是当前行的结尾。

{
  for pc in {1..100}; do
    #echo -ne "$pc%\033[0K\r"
    echo -ne "\r\033[0K${pc}%"
    sleep 1
  done
  echo
}

答案 3 :(得分:5)

通常是{p> printf '\r'。在这种情况下,没有理由进行光标寻址。

答案 4 :(得分:3)

要真正擦除上一个行,而不仅仅是当前行,可以使用以下bash函数:

# Clears the entire current line regardless of terminal size.
# See the magic by running:
# { sleep 1; clear_this_line ; }&
clear_this_line(){
        printf '\r'
        cols="$(tput cols)"
        for i in $(seq "$cols"); do
                printf ' '
        done
        printf '\r'
}

# Erases the amount of lines specified.
# Usage: erase_lines [AMOUNT]
# See the magic by running:
# { sleep 1; erase_lines 2; }&
erase_lines(){
        # Default line count to 1.
        test -z "$1" && lines="1" || lines="$1"

        # This is what we use to move the cursor to previous lines.
        UP='\033[1A'

        # Exit if erase count is zero.
        [ "$lines" = 0 ] && return

        # Erase.
        if [ "$lines" = 1 ]; then
                clear_this_line
        else
                lines=$((lines-1))
                clear_this_line
                for i in $(seq "$lines"); do
                        printf "$UP"
                        clear_this_line
                done
        fi
}

现在,只需调用erase_lines 5即可清除终端中的最后5行。

答案 5 :(得分:0)

echo -n "foo"也会在没有新行的情况下打印它。

答案 6 :(得分:0)

man terminfo(5)并查看“ cap-nam”列。

clr_eol=$(tput el)
while true
do
    printf "${clr_eol}your message here\r"
    sleep 60
done