如何删除回声行?


59

我知道我可以使用以下命令删除最后三个字符:

echo -ne '\b\b\b'

但是,如何删除整行?我的意思是我不想使用:

echo -ne '\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b'

... etc ...删除长行。


2
对于那些想连续在同一行上写的人:echo -ne "\033[2K" ; printf "\r",现在该行就像新行一样好,好像以前从未写过一样。
Hello World

2
我确定您可以使用echo -ne "\e[2K\r"。但是,ANSI转义序列为FTW。
Parthian Shot 2015年

Answers:


56

您可以使用\b或向后\r移动光标,然后用新字符覆盖打印的字符。请注意,也\b不会\r删除打印的字符。它只是将光标移回。\b将光标移回一个字符,然后\r将光标移至该行的开头。

示例:两者

echo -e 'foooo\b\b\b\b\bbar'

echo -e 'foooo\rbar'

将打印:

baroo

如果要删除字符,则必须使用以下解决方法:

echo -e 'fooooo\r     \rbar'

输出:

bar  

摘录自man echo

   If -e is in effect, the following sequences are recognized:

   \0NNN  the character whose ASCII code is NNN (octal)

   \\     backslash

   \a     alert (BEL)

   \b     backspace

   \c     produce no further output

   \f     form feed

   \n     new line

   \r     carriage return

   \t     horizontal tab

   \v     vertical tab

   NOTE: your shell may have its own version of echo, which usually super‐
   sedes the version described here.  Please refer to your  shell's  docu‐
   mentation for details about the options it supports.

4
是的,但echo -e 'fooooooooo\rbar呼应barooooooo。
垫子

1
是的,你是对的。请注意,它echo -e 'foooo\b\b\b\b\b\b\b\b\b\bbar'也会回显baroo
lesmana 2011年

如此甜蜜,甚至可以完美地在中工作printf
Michael-O

4
答案很不准确。凯文(Kevin)的球真的更好
Mike Aski

87

您正在寻找候机楼。特别是要清除从光标位置到行首的内容:

echo -e "\033[1K"

或行中的所有内容,无论光标处于什么位置:

echo -e "\033[2K"

您也可以使用终端转义符来做各种其他巧妙的技巧。


6
假定使用兼容VT100的终端或仿真器(目前这是一个非常安全的假设)。
Keith Thompson

2
如果要擦除刚刚回显的内容,则先前的回显必须带有-n标志,否则您将被发送到新行
djjeck 2014年

1
如果要编写其他内容,请在要擦除的行上,在上面的回显上添加-n标志,否则将其删除后直接转到新行。另外,在上面的字符串后附加\ r,否则您的新内容将不会移至该行的开头。
djjeck 2014年

-1 | -e因为echo参数不符合POSIX +我不喜欢转义序列。选择printf还是tput
LinuxSecurityFreak '18

@Vlastimil为什么您会对此投反对票?OP并未要求您提供想要的答案。也许他应该已经精确说明了该-e参数echo不符合POSIX,但仍然...
souki

35

如果您想清除行,那么我建议您使用回车人提到的回车和terminfo的组合。

# terminfo clr_eol
ceol=$(tput el)
echo -ne "xyzzyxyzzy\r${ceol}foobar"

这将写入xyzzyxyzzy,然后返回到行的开头,并将“清除到行尾”序列发送到终端,然后写入foobar。在-n之后的品牌回声无法添加新行foobar


4
我喜欢此特定解决方案的面向未来的部分-使用tput可能意味着它可以在任何类型的终端上使用。
阿莫斯·夏皮拉

2
为更好printf '%s\r%s%s' xyzzyxyzzy "$ceol" foobar的便携性,并避免的内容$ceol通过持续\x扩张。
斯特凡Chazelas

最好的答案是仅因为它适用于任意长的行。谢谢!
拉斐尔

做工完美。但是,如果我将终端屏幕的尺寸调整为小于输出线的尺寸,则会变得混乱。
K.Sopheak

11

您明确要求echo,但此请求将您锁定。这是一种将bash的内置printf命令与大括号扩展一起使用的方法:

printf 'fooooooooo' # 10 characters
printf '\r'; printf ' %0.s' {0..9} # 10 expansions of the space character

1
完善!正是我所需要的
Omar S.

2
printf'状态:已启动';睡眠2s; printf'\ r'; printf'状态:已更新';睡眠2s; printf'\ r';
Omar S.

4

这是一个使用echo的no换行符 -n回车 \r选项的示例。

bash覆盖终端线

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

复选标记甚至可以在RHEL6上使用。非常适合我的脚本的纯粹美学编辑
oneindelijk

1

取而代之的是echo -en "\r",该printf "\r"命令也很有用。这样,您可以格式化字符串。例如:

for sec in {1..100}; do printf "\r %04d" ${sec}; sleep 0.1; done

在处理缓慢的文件解析以显示当前正在进行的文件名而不创建列表时,我通常也会这样做


-1 | 也许您想有意做成单线,但这实际上仅对测试有用。我会用新行正确地重写它。
LinuxSecurityFreak '18

0

问题是删除整行

我在下面的命令中使用了echo和的组合sed以删除行

执行命令后,结果将为空,因为那一行将被替换为none

命令

echo  "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" | sed -r "s/.*//g"

-1

这是我使用的倒数计时器示例:

i=10
while [ $i -gt 0 ]; 
do 
  printf "$i seconds remaining       " && printf '\r\033[1B'
  i=`expr $i - 1`
  sleep 1
  printf '\033[1A'
done

-1 | 也许您想有意做成单线,但这实际上仅对测试有用。我会用新行正确地重写它。
LinuxSecurityFreak '18

然后,继续并添加新答案。或建议对我的答案进行修改。
mikiemorales
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.