| | Stumble It! | Add to Mixx! | | diigo it | | Slashdot |

Tuesday, February 23, 2010

Simple BASH Progress Bar Function

A recent task at work had me work up a script to automate an extremely repetitive and boring task that had approximately 1700 iterations. That means:
  1. Load a web page
  2. Copy/paste two pieces of information into Excel
  3. Repeat ...
  4. ... 1700+ times
Luckily I was able to script the whole process so it took me about 30 minutes of building the script and then about 2.5 hours of letting the script run in the background.

During that 2.5 hours, I found myself wondering "Gosh, is that thing done yet!?" and wishing that I had some way to tell how close it was to being done. So I used that time to build a small BASH function that will give a progress bar in your terminal window to show the progress of a given script.

To use it, you just need to paste the function into the top of your script and then in your for or while loop, add the line below and it will build the bar for you.
showBar $<counter variable> $<total iterations>
And here is the code:
#!/bin/bash

function showBar {
percDone=$(echo 'scale=2;'$1/$2*100 | bc)
barLen=$(echo ${percDone%'.00'})
bar=''
fills=''
for (( b=0; b<$barLen; b++ ))
do
bar=$bar"="
done
blankSpaces=$(echo $((100-$barLen)))
for (( f=0; f<$blankSpaces; f++ ))
do
fills=$fills"_"
done
clear
echo '['$bar'>'$fills'] - '$barLen'%'
}
The example below shows how to include the showBar function in a for loop:
for (( i=0; i<=245; i++ ))
do
showBar $i 245
done
I wouldn't be at all surprised if there is a better, more elegant way to accomplish this, but this is how I did it.

Cheers!

Thursday, February 11, 2010

Multi-Dimensional Associative Arrays in BASH ... Sort of...

I found this little gem of BASH scripting today and wanted to share it here, mostly because I find that it fills a function that I'm constantly trying to remember, "How did I do that in the last script I wrote?"

NOTE - If you know a better way to accomplish this task, please let me know!

The following snippet of code will let you loop through a delimited text file (commas, semi-colons, tab, etc.) and assign the values to variables for scripting goodness. For this example, assume that I'm using the following source file: MyIps.csv
192.168.1.1,My Linksys
192.168.1.2,My Server
192.168.1.3,My Desktop
192.168.1.4,My Laptop
Using this as a source file, this is the script that will let me loop through the file as though it were a multi-dimensional associative array:
#!/bin/bash
OLD_IFS=$IFS
IFS=','
while read ip desc # these are the various items in the MyIps.csv
do
echo $ip' - '$desc
done < MyIps.csv
IFS=$OLD_IFS

Obviously, if your source file uses a delimiter other than a comma, you'll have to modify the script to accommodate for that.

Cheers!