How to show and update echo on same line
Well I did not read correctly the man echo
page for this.
echo had 2 options that could do this if I added a 3rd escape character.
The 2 options are -n
and -e
.
-n
will not output the trailing newline. So that saves me from going to a new line each time I echo something.
-e
will allow me to interpret backslash escape symbols.
Guess what escape symbol I want to use for this: \r
. Yes, carriage return would send me back to the start and it will visually look like I am updating on the same line.
So the echo line would look like this:
echo -ne "Movie $movies - $dir ADDED!"\\r
I had to escape the escape symbol so Bash would not kill it. that is why you see 2 \
symbols in there.
As mentioned by William, printf
can also do similar (and even more extensive) tasks like this.
I use printf, it's shorter as it doesn't need flags to do the work:
printf "\rMy static $myvars composed text"
If I have understood well, you can get it replacing your echo with the following line:
echo -ne "Movie $movies - $dir ADDED! \033[0K\r"
Here is a small example that you can run to understand its behaviour:
#!/bin/bash
for pc in $(seq 1 100); do
echo -ne "$pc%\033[0K\r"
sleep 1
done
echo
The rest of answers are pretty good, but just wanted to add some extra information in case someone comes here looking for a solution to replace/update a multiline echo.
So I would like to share an example with you all. The following script was tried on a CentOS system and uses "timedatectl" command which basically prints some detailed time information of your system.
I decided to use that command as its output contains multiple lines and works perfectly for the example below:
#!/bin/bash
while true; do
COMMAND=$(timedatectl) #Save command result in a var.
echo "$COMMAND" #Print command result, including new lines.
sleep 3 #Keep above's output on screen during 3 seconds before clearing it
#Following code clears previously printed lines
LINES=$(echo "$COMMAND" | wc -l) #Calculate number of lines for the output previously printed
for (( i=1; i <= $(($LINES)); i++ ));do #For each line printed as a result of "timedatectl"
tput cuu1 #Move cursor up by one line
tput el #Clear the line
done
done
The above will print the result of "timedatectl
" forever and will replace the previous echo with updated results.
I have to mention that this code is only an example, but maybe not the best solution for you depending on your needs.
A similar command that would do almost the same (at least visually) is "watch -n 3 timedatectl
".
But that's a different story. :)
Hope that helps!