bash 脚本,删除前一行?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5861428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 23:54:50  来源:igfitidea点击:

bash script, erase previous line?

bash

提问by Matt

In lots of Linux programs, like curl, wget, and anything with a progress meter, they have the bottom line constantly update, every certain amount of time. How do I do that in a bash script? All I can do now is just echo a new line, and that's not what I want because it builds up. I did come across something that mentioned "tput cup 0 0", but I tried it and it's kind of quirky. What's the best way?

在许多 Linux 程序中,例如 curl、wget 和任何带有进度表的程序,它们的底线都是每隔一定时间不断更新的。我如何在 bash 脚本中做到这一点?我现在能做的只是回显一个新行,这不是我想要的,因为它会建立起来。我确实遇到过一些提到“tput cup 0 0”的东西,但我试过了,它有点古怪。最好的方法是什么?

回答by linuts

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

The "\033[0K" will delete to the end of the line - in case your progress line gets shorter at some point, although this may not be necessary for your purposes.

"\033[0K" 将删除到行尾 - 以防您的进度线在某些时候变短,尽管这对于您的目的可能不是必需的。

The "\r" will move the cursor to the beginning of the current line

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

The -n on echo will prevent the cursor advancing to the next line

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

回答by Lri

You can also use tput cuu1;tput el(or printf '\e[A\e[K') to move the cursor up one line and erase the line:

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

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

回答by tom

Small variation on linuts' code sample to move the cursor not to the beginning, but the end of the current line.

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

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

回答by geekosaur

printf '\r', usually. There's no reason for cursor addressing in this case.

printf '\r', 通常。在这种情况下没有理由进行游标寻址。

回答by aggregate1166877

To actually erase previouslines, not just the current line, you can use the following bash functions:

要真正擦除以前的行,而不仅仅是当前行,您可以使用以下 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 "" && lines="1" || lines=""

        # This is what we use to move the cursor to previous lines.
        UP='3[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
}

Now, simply call erase_lines 5for example to clear the last 5 lines in the terminal.

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

回答by anubhava

echo -n "foo"also prints it without a new line in the end.

echo -n "foo"最后也没有换行就打印出来。