我的bash-script看起来如下:
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
它读取desc var直到传递空行。在那之后,我想阅读其他内容。
执行当前脚本时,它看起来像这样:
Description:
Line 1
Line 2
Maintainer:
我想用“Maintainer:”覆盖最后一个空行。
我搜索了一个解决方案,但只找到了像
这样的建议echo -n "Old line"
echo -e "\r new line"
保留在线上并覆盖它。在我的情况下,这是不可能的。
答案 0 :(得分:67)
只需使用"\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
。
答案 1 :(得分:12)
我从Dennis Williamsons Comment构建了一个函数:
function clearLastLine() {
tput cuu 1 && tput el
}
感谢Dennis Williamson
答案 2 :(得分:11)
找到了一个不错的guide on escape sequences,并希望在这里展开一些讨论。
当您写出一个终端时,您将移动一个不可见的光标,就像在任何文本编辑器中编写时一样。使用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
中有效,但是{{1} }对所有这些都有效。如果您希望脚本在任何地方都可以使用,则应首选\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$@"; }
只是将函数的所有参数放入字符串中
$@
希望能帮助想了解更多信息的人。
答案 3 :(得分:5)
如果您在没有换行符echo -n "Something"
的情况下回音,则可以使用\r
与下一个回音移动&#39; 光标&#39;到行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"
请注意,如果您的新字符串比旧字符串短,则旧字符串的尾部仍然可见。请注意上面gif中的done..
。
答案 4 :(得分:1)
#!/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]”。
答案 5 :(得分:0)
如果您想循环运行脚本而又不破坏回滚,则可以使用以下模式:
while sleep 10s; do
echo -n $(script)
echo -n -e "\e[0K\r"
done
只需将script
命令替换为您自己的命令即可。