79

I know that I could delete the last three chars with:

echo -ne '\b\b\b'

But how can I delete a full line? I mean I don't want to use:

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... to delete a long line.

3
  • 6
    For those who'd like to continuously write on the same line: echo -ne "\033[2K" ; printf "\r", now the line is good as new, as if it was never written to before. Oct 18, 2014 at 14:33
  • 3
    I'm pretty sure you can just use echo -ne "\e[2K\r". But ANSI escape sequences FTW, nonetheless. Feb 4, 2015 at 18:15
  • 1
    Also see Why is printf better than echo?
    – Wildcard
    Nov 8, 2016 at 9:16

8 Answers 8

142

You're looking for terminal escapes. In particular, to clear from the cursor position to the beginning of the line:

echo -e "\033[1K"

Or everything on the line, regardless of cursor position:

echo -e "\033[2K"

And you can do all sorts of other neat tricks with terminal escapes too.

6
  • 13
    This assumes a VT100-compatible terminal or emulator (which is a pretty safe assumption these days). Dec 12, 2011 at 1:46
  • 3
    If you want to erase something you just echoed, your previous echo must have the -n flag, or you'll be sent to a new line
    – djjeck
    Nov 20, 2014 at 1:45
  • 1
    If you want to write something else, on the line you're erasing, add a -n flag on the echo above, or else you'll go to a new line right after deleting it. Also, append a \r to the string above, or your new content won't go to the beginning of that line.
    – djjeck
    Nov 20, 2014 at 1:46
  • -1 | -e as echo argument is not POSIX compliant + I don't like the escape sequences. Either prefer printf or tput. Feb 3, 2018 at 10:23
  • @Vlastimil why would you downvote this? OP didn't ask for an answer that you would like. Maybe he should have precised that -e parameter for echo is not POSIX compliant but still...
    – souki
    May 21, 2018 at 10:01
66

You can use \b or \r to move the cursor back and then overwrite the printed character with a new character. Note that neither \b nor \r deletes the printed characters. It just moves the cursor back. \b moves the cursor back one character and \r moves the cursor to the beginning of the line.

Example: both

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

and

echo -e 'foooo\rbar'

will print:

baroo

If you want the characters deleted then you have to use the following workaround:

echo -e 'fooooo\r     \rbar'

output:

bar  

Excerpt from 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.
5
  • 4
    Yes, but echo -e 'fooooooooo\rbar echoes barooooooo.
    – Mat
    Dec 11, 2011 at 11:40
  • 1
    Yes you are right. Note that echo -e 'foooo\b\b\b\b\b\b\b\b\b\bbar' also echoes baroo.
    – Lesmana
    Dec 11, 2011 at 11:46
  • So sweet, works even flawlessly in printf.
    – Michael-O
    Jun 6, 2013 at 15:07
  • 10
    Very unaccurate answer. Kevin's one is really better
    – Mike Aski
    Jun 15, 2016 at 15:47
  • You're not answering the OP's question. Kevin's answer is the correct one. Dec 29, 2019 at 13:16
37

If you want to clear the line, then I suggest you use a combination of the carriage return people are mentioning and terminfo.

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

This will write xyzzyxyzzy, then return to the beginning of the line and send the "clear to end of line" sequence to the terminal, then write foobar. The -n makes echo not add a newline after the foobar.

4
  • 4
    I like the sort of future-proofing part of this specific solution - using tput possibly means that it'll work on any kind of terminal. Nov 6, 2014 at 1:36
  • 2
    Better as printf '%s\r%s%s' xyzzyxyzzy "$ceol" foobar for portability and to avoid having the content of $ceol going through \x expansion. Nov 8, 2016 at 9:49
  • Best answer if only because it works with arbitrarily long lines. Thanks!
    – Raphael
    Jul 5, 2018 at 13:06
  • work perfect. But if i resize terminal screen smaller than output line, it becomes messy.
    – K.Sopheak
    Apr 3, 2019 at 8:36
13

Here's an example using echo's no newline -n and carriage return \r options.

bash overwrite terminal line

#!/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"
1
  • 2
    Check mark works even on RHEL6. Nice for purely aesthetical edits of my scripts Aug 28, 2019 at 11:40
12

You explicitly ask for echo, but this request pins you down. Here's an approach that uses bash's builtin printf command with brace expansion:

printf 'fooooooooo' # 10 characters
printf '\r'; printf ' %0.s' {0..9} # 10 expansions of the space character
2
  • 1
    perfect! exactly what I needed
    – Omar S.
    Mar 26, 2013 at 17:09
  • 2
    printf 'Status: started';sleep 2s;printf '\r';printf 'Status: updated';sleep 2s;printf '\r';
    – Omar S.
    Mar 26, 2013 at 17:15
1

Instead of echo -en "\r" you might also find the printf "\r" command as useful. This way you can format the string. e.g.:

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

I usually do that as well when operating with slow file parsing to display the filename currently in progress without creating a list

1
  • -1 | Maybe you wanted to intentionally make a one-liner, but that's actually only good for testing. I would re-write it properly with new lines. Feb 3, 2018 at 8:05
0

As question is delete the full line

I have used below command with combination of echo and sed to delete line

After execution of command result will be empty.since while line will be replaced with none

command

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"
0

Here is a countdown timer example I use:

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
2
  • -1 | Maybe you wanted to intentionally make a one-liner, but that's actually only good for testing. I would re-write it properly with new lines. Feb 3, 2018 at 8:05
  • Then, go ahead and do it and add a new answer. Or propose an edit of my answer. Feb 4, 2018 at 2:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.