How to display a counter in shell script?

Hi,
I am writing a script which processes large number of files in a directory. I wanto display a counter which increment after processing each file. I am processing each file in a for loop. If I echo a variable with its value increasing with each file, I will get around 5000 lines as output. Instead I wish to display a count - like a digital clock- which increases at the same position and line.

Can anyone help with any command to achieve this?

Thanks
Jaise

Something like this?

for ((i=0; i<120; i++))
do
    printf '\r%3d' $i
    sleep .5
done
echo
START=$( date +%s ); while true; do CURRENT=$( date +%s ) ; echo $(( CURRENT-START )) ; sleep 1 ; echo -n  ; done

Hi,
Thanks for the quick replies.
here is the code I wrote.

ls -lrt *.txt |awk '{print $9}' > $HOME/file.list                                                                          
for file in `cat $HOME/file.list`                                  
   do                                                                  
     echo " Processing $file" >>$HOME/file_process.log
     $EXEC/xxx.exe $file      >>$HOME/file_process.log                             

   done        

In the file.list, there will be around 5000 entries. If I put a normal print or echo command inside the loop, the output will be displayed 5000 times. I dont want this to happen. Still I want to know th eprogress of the activity.

If I use a normal counter by using a variable increment by one on each execution of the loop, output will be like this

1
2
3
4
5
6
7
.
.
.

I want to know if it is possible to display 1, then 2 at the position of 1, then 3 at the position of 2 and so on... I mean like a digital clock.

Any luck?

Hi Jaiseaugustine,

take a perameter file with counter. once each file process completed then update the parameter file.

code :

cd $src_dir_path
TXT1=`cat Parameter.txt | grep "Counter=" | head -1` ;
FTXT1=`cat Parameter.txt .txt | grep "Counter=" | awk -F"=" '{print $1}' | head -1` ;
FTXT2=`cat Parameter.txt .txt | grep "Counter=" | awk -F"=" '{print $2}' | head -1` ;
NTXT=`expr ${FTXT2} + 1` ;
sed "s/$TXT/$FTXT"="$DT/g" Parameter.txt > Parameter_temp.txt ;
cp Parameter_temp.txt Parameter.txt
sed "s/$TXT1/$FTXT1"="$NTXT/g" Parameter.txt > Parameter.txt_temp.txt;
cp Parameter_temp.txt Parameter.txt .txt
chmod 777 Parameter.txt.txt
chmod 777 Parameter_temp.txt

parameter file should be like this:
Parameter.txt:

Counter=0

regadrs
rajesh

Did you read the above posts? Did you try some of the things posted there? If you want a read-to-go solution without having to do anything yourself, say so, but this will probably put people off from helping you.

This works with ksh, bash and dash

cnt=0                        
# if you need only  files which names are *.txt, then no need ls+awk                                    
for file in *.txt                           
do                    
     cnt=$((cnt+1))
    # -n = no newline and -e needed if your echo not accept \r
    # \r carriage return - cursor to the position 1
     echo -n -e  "\r$cnt $file                                     "                                              
     $EXEC/xxx.exe $file      >>$HOME/file_process.log                             
done
echo 
echo "The End"
1 Like

Just use printf and you won't have to worry about whether your echo supports -e \r -- all printf supports \r. You can also specify %3d to keep the number nicely aligned.

printf "\r%3d %s" $cnt $file

Hi,
Thank you kshji for your help. Your code gave me the correct logic.. Now the below code works perfectly.. :slight_smile:

cnt=0                                 
bal=`ls -lrt *.txt |wc -l`                                              
for file in *.txt                           
do                    
     cnt=$((cnt+1))
     bal=$((bal-1))
     echo  "\rProcessed Files :: $cnt Remaining ::$bal\c"                    
     $EXEC/xxx.exe $file      >>$HOME/file_process.log                             
done
echo 
echo "Processing completed"

One word to pludi
" I tried your code and didn't work. Thanks."

Thanks to all replied.
Jaise

Pludi's code works fine under bash while I guess you are running ksh which doesn't implement a sub second sleep builtin.

I would slightly modify two lines of your script:

bal=`ls -lrt *.txt |wc -l`

"-lrt" is unnecessary as you only count the number of files anyway:

bal=$(ls *.txt |wc -l)
echo  "\rProcessed Files :: $cnt Remaining ::$bal\c"

As already advised, better to use printf which is standard and portable instead of implementation specific echo oddities:

printf "\rProcessed Files :: %4d Remaining ::%4d " $cnt $bal
1 Like

Hi,
I was trying in ksh. May be thats why it didnt work for me..
thanks to all replied...:slight_smile:

Regards.
Jaise