Overwrite previous output in Bash instead of appending it

Solution 1:

Basically the same as aneeshep's answer, but uses Return (\r) rather than Backspace (\b) because we don't know if the length will always be the same, e.g. when $sek < 10.

Also, your first echo should use $sek, not hard-code 60.

Finally, note the space after the ....

#!/bin/bash
sek=60
echo "$sek Seconds Wait!"
while [ $sek -ge 1 ]
do
   echo -ne "One Moment please $sek ... \r"
   sleep 1
   sek=$[$sek-1]
done
echo
echo "ready!"

Solution 2:

#!/bin/bash
sek=60
echo "60 Seconds Wait!"
echo -n "One Moment please "
while [ $sek -ge 1 ]
do
   echo -n "$sek" #print sek
   sleep 1
   sek=$[$sek-1] #update sek
   echo -en "\b\b\b" #'print' backtrace
done
echo
echo "ready!"

Solution 3:

With bash you can use the special variable SECONDS.

#BASH
SECONDS=0;
while sleep .5 && ((SECONDS <= 60)); do 
    printf '\r%s: %2d' "One moment please" "$((60-SECONDS))"
done
printf '\n'

Solution 4:

In addition to \r or \b approaches, it's possible to use the \033[2K control character, which tells the terminal to clear the whole line. The advantage of this compared to \b is that you don't have to match number of \b with the amount of characters you want to delete, and compared to \r there won't be characters sticking out on the screen if the new line is shorter than the old one.

Below is the example of how it can be applied to this question, and here is an example of the related application to create output similar to boot messages. In this particular example, the timer will be gone once 0th second is reached and the timer line will be replaced with "Ready!" phrase.

#!/bin/bash
sek=60
echo "60 Seconds"

while ((sek--)); do
    printf "One moment please: %d" "$sek"
    sleep 1
    printf "\r%b" "\033[2K"
done
echo "Ready!"

Another alternative would be to employ dialog command for creating simple dialogs in command-line. The dialog will remain on screen for the duration of the timer and update with the loop, and by the time it's done - the timer will be replaced with "Ready! Press to exit" message in a seamless manner:

#!/bin/bash
sek=60
echo "60 Seconds"

while ((sek--)); do
    echo "$sek" | dialog --progressbox "Please wait" 10 25
    sleep 1
done
dialog --msgbox "Ready! Press <OK> to finish" 10 25

Solution 5:

This is what I came up with after reading here and a bit more, the one liner:

SEC=101;for i in `seq $SEC -1 1`;do printf "\rNext in: %`expr length $SEC`ds" "$i";sleep 1;done;echo

More readable:

#!/bin/bash
SEC=101

for i in `seq $SEC -1 1`;do
        printf "\rNext in: %`expr length $SEC`ds" "$i";
        sleep 1;
done
echo

Where SEC can be set to whatever positive integer and the printf will take care of appropriate padding. Tested under Ubuntu and cygwin.