How to show and update echoes on one line

I have the following in Bash (on Linux)

for dir in Movies/* do (cd "$dir" && pwd|cut -d \/ -f5|tr -s '\n' ', ' >> ../../movielist && exiftool * -t -s3 -ImageSize -FileType|tr -s '\t' ',' >> ../../movielist ) echo "Movie $movies - $dir ADDED!" let movies=movies+1 done 

But I want to make the "echo" display the next echo on the next line (not concatenation with the last output of the echo, but replacing it) so that it looks like it is being updated. Similar to how a progress bar with a percentage will be displayed on one line.

+82
bash
Sep 27 '12 at 18:58
source share
6 answers

Well, I did not read the man echo page correctly for this.

There were 2 options in echo that could do this if I added a third escape character.

2 options: -n and -e .

-n does not print a trailing newline. So this saves me from going to a new line every time I repeat something.

-e will allow me to interpret backslash characters.

Guess which escape character I want to use for this: \r . Yes, carriage return will return me to the beginning, and it will visually look as if I am updating on the same line.

So, the echo line will look like this:

echo -ne "Movie $movies - $dir ADDED!"\\r

I had to escape from the escape character, so Bash will not kill it. therefore you see there 2 \ .

As mentioned by William, printf can also perform similar (and even more extensive) tasks like this.

+147
Sep 27 '12 at 19:10
source share
β€” -

If I understand well, you can force it to replace 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 behavior:

 #!/bin/bash for pc in $(seq 1 100); do echo -ne "$pc%\033[0K\r" sleep 1 done echo 
+55
Sep 27 '12 at 19:11
source share

The rest of the answers are pretty good, but I just wanted to add more information in case someone comes here looking for a solution to replace / update a multi-line echo.

Therefore, I would like to share an example with all of you. The following script has been tested on CentOS and uses the "timedatectl" command, which basically displays some detailed information about your system’s time.

I decided to use this command because its output contains several lines and works fine 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 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 

Above will print the result of " timedatectl " forever and replace the previous echo with updated results.

I should mention that this code is just an example, but maybe not the best solution for you, depending on your needs. A similar command that will do almost the same thing (at least visually) is " watch -n 3 timedatectl ".

But this is a different story. :)

Hope this helps!

+12
Dec 16 '16 at 19:40
source share

This is useful, please try and modify as necessary.

 #! bin/bash for load in $(seq 1 100); do echo -ne "$load % downloded ...\r" sleep 1 done echo "100" echo "Loaded ..." 
+2
Feb 17 '18 at 12:50
source share

My favorite way is called do sleep to 50. here i should use the variable inside the echo statements.

 for i in $(seq 1 50); do echo -ne "$i%\033[0K\r" sleep 50 done echo "ended" 
+1
Jan 16 '18 at 17:49
source share

You can try this .. My own version of this ..

 funcc() { while true ; do for i in \| \/ \- \\ \| \/ \- \\; do echo -n -e "\r$1 $i " sleep 0.5 done #echo -e "\r " [ -f /tmp/print-stat ] && break 2 done } funcc "Checking Kubectl" & &>/dev/null sleep 5 touch /tmp/print-stat echo -e "\rPrint Success " 
+1
Jan 11 '19 at 9:58
source share



All Articles