覆盖终端上最后一行(Overwrite last line on terminal)

2019-07-30 05:04发布

我的bash脚本看起来如下:

echo "Description:"
while [ $finishInput -eq 0 ]; do
read tmp
desc="$desc"$'\n'"$tmp"
if [ -z "$tmp" ]; then
finishInput="1"
fi
done
echo -n "Maintainer:"
read maintainer

直到一个空行通过它读取的递减变种。 在那之后,我想其他的东西阅读。

当执行我当前的脚本,它看起来是这样的:

Description:
Line 1
Line 2

Maintainer:

我想覆盖的最后一个空行的“维护者”。

我搜索了一个解决方案,但只发现了其中像建议

echo -n "Old line"
echo -e "\r new line"

它可以停留在行并将其覆盖。 这是不可能在我的情况。

Answer 1:

只要使用"\e[1A"

在您的例子,你删除同一行的文本:

$ echo -n "Old line"; echo -e "\e[0K\r new line"
 new line

当你想回到上一行用\ E [1A:

$ echo "Old line"; echo -en "\e[1A"; echo -e "\e[0K\r new line"
 new line

当你想要去的N行了,使用\e[<N>A



Answer 2:

我内置从功能丹尼斯Williamsons评论 :

function clearLastLine() {
        tput cuu 1 && tput el
}

由于丹尼斯威廉姆森



Answer 3:

发现了一个伟大的转义序列指导 ,并希望在这里的一些讨论扩大。

当你写出来的终端,如果你移动一个无形的光标,当你在任何文本编辑器编写很多像你一样。 当使用echo ,它会自动结束与该光标移动到下一行一个新行字符的输出。

$ echo "Hello" && echo " World"
Hello
 World

您可以使用-n以防止新的生产线,如果你在这之后再次呼应,将其追加到该行的末尾

$ echo -n "Hello" && echo " World"
Hello World

光标率仍然是如此,在它自己的,我们不能用-n覆盖前行,我们需要将光标移动到左侧。 要做到这一点,我们需要给它一个转义序列,这是我们让echo知道我们要与使用-e ,然后通过提供返回滑架移动光标\r这使光标在该行的开头。

$ echo -n "Hello" && echo -e "\rWorld"
World

这可能看起来像它的工作,但看到发生了什么

$ echo -n "A longer sentance" && echo -e "\rShort sentance"
Short sentancence

见多余的字符? 简单地写在一行,仅会更改我们写他们的字符。

为了解决这个问题,接受的答案上面使用转义字符\e[0K光标后删除所有内容,将光标移动离开后。 即\r移动到开始\e[0K擦除结束。

$ echo -n "A longer sentance" && echo -e "\r\e[0KShort sentance"
Short sentance

重要的 \e开始转义序列工作在zsh而不是在sh的,不一定是bash ,但\033工作在所有。 如果你希望你的脚本在任何地方工作,你应该偏好\033

$ echo -n "A longer sentance" && echo -e "\r\033[0KShort sentance"
Short sentance

但是转义字符可以提供更加实用。 例如\033[1A将光标移动到上一行,所以我们不需要-n上一回声:

$ echo "A longer sentance" && echo -e "\r\033[1A\033[0KShort sentance"
Short sentance

\r移动到开始\033[1A向上移动\033[0K擦除到端

最后,这是在我的书都有点乱,所以你可以把它变成一个功能:

overwrite() { echo -e "\r\033[1A\033[0K$@"; }

使用$@只是把函数的所有参数到字符串

$ echo Longer sentance && overwrite Short sentence
Short sentence

希望帮助想知道谁多一点的人。



Answer 4:

如果你不呼应的换行符echo -n "Something" ,你可以使用\r您的下一个回声的“ 光标 ”移动到行的开头echo -e "\\rOverwrite something"

#!/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"

要知道,如果你的新字符串是短于旧线,旧串的尾部仍可见。 注意done..在上面的gif。



Answer 5:

#!/bin/bash

echo "Description:"
while test -z $finishInput; do
 read -s tmp
 desc="$desc"$'\n'"$tmp"
 if [ -z "$tmp" ]; then
 finishInput=1
 else
    echo $tmp
 fi
 #echo "fi="$finishInput;
done
echo -n "Maintainer:"
read maintainer

该解决方案避免了空行,但行完成之前输入不回显。

提示:我的bash的版本并没有接受 “[$ finishInput -eq 0]”。



Answer 6:

如果你想在一个循环中运行一个脚本,而不是炸毁你的回溯,可以使用以下模式:

while sleep 10s; do 
  echo -n $(script)
  echo -n -e "\e[0K\r"
done

只需更换script用自己的命令。



文章来源: Overwrite last line on terminal