Here's a little something I wrote a while ago to graph some data on a text-only terminal.
Save it as
graph.fnc and source it in the script you want to use it in.
Then just call the
graph function as in the 'Usage' comment

Code:
#!/bin/bash
## graph.fnc -- by Patsie
# Shell function that draws a graph with average line in ASCII
# The graph will have a width equal to the number of data points
# and a height equal to the first argument
# Usage: graph <height> <val1> [<val2> [<...>]]
function graph {
height=$1; shift;
echo "$@" | awk -v height=$height 'BEGIN { }
## convert big numbers to short kilo/mega/giga etc numbers
function pow1k(bignum) {
metric=1;
num=bignum;
# devide by 1000 until we have got a small enough number
while (num>=1000) { metric++; num/=1000; }
num=int(num);
# get SI prefix (kilo, mega, giga, tera, peta, exa, zotta, yotta)
si=substr(" KMGTPEZY", metric, 1);
# get a division remainder to total our number of characters to a maximum of 4
division=substr(bignum, length(num)+1, 3-length(num));
# right align the output
str=sprintf("%s%c%s", num, si, division);
return(sprintf("% 4s", str));
}
{
# get smallest, largest and total of all numbers
min=max=tot=$1;
for (x=2; x<=NF; x++) { tot+=$x; if ($x>max) max=$x; if ($x<min) min=$x; }
# the difference between largest and smallest number is out working area
diff=max-min;
if (diff==0) diff=1; # all numbers are the same?!
# some fancy math to get the average of all numbers
avg=(tot/NF);
avgfull=int(((avg-min)*height/diff)); # average full
avghalf=int(((avg-min)*height/diff)%1+0.5); # average half
# fill arrays bars
for (x=1; x<=NF; x++) {
v=$x-min; # our value
i=0;array[x]=""; # blank the array
full=int((v*height/diff)); # how many full?
ttrd=int((v*height/diff)%1+0.333); # 2/3rd full?
otrd=int((v*height/diff)%1+0.666); # 1/3rd full?
while (i<full) { array[x]=array[x]"O"; i++; } # fill all fulls
if (ttrd>0) { array[x]=array[x]"o"; i++; } # fill 2/3rd
else if (otrd>0) { array[x]=array[x]"."; i++; } # or 1/3rd
# average line or blank
while (i<height) { # fill to the top
if (i==avgfull) # with average line
if (avghalf>0) array[x]=array[x]"-";
else array[x]=array[x]"_";
else array[x]=array[x]" "; # or mostly blanks
i++;
}
}
# display output
for (y=height; y>0; y--) {
line=""; num=" "; # blank line and number
if (y==avgfull+1) { num=pow1k(int(avg)); } # show average number
if (y==height) { num=pow1k(max); } # show maximum number
if (y==1) { num=pow1k(min); } # show minimum number
for (x=1; x<=NF; x++) # do for all data values
line=line""substr(array[x],y,1); # create line from arrays
printf(" %s | %s | %s\n", num, line, num); # display 1 line
}
}'
}
And here's an example how to use it. It will plot a graph with random data and simulate 100 times getting a new data point.
Be sure that
graph.fnc is in your current directory.
Code:
#!/bin/bash
## graphtest.sh -- by Patsie
# Draw a graph using an ASCII graph function
# The graph will have a width equal to the number of data points
# and a height equal to the first argument
# Usage: graphtest.sh
## Should the graph move from right to left or vice versa
right_to_left=1
## include graphing function
. ./graph.fnc
## starting value, fill graph data
val=100000
data=`for i in $(seq 60); do echo $((val+=RANDOM%1000-500)); done`
i=0
clear
## repeat 100 times
while [ $((i++)) -lt 100 ]; do
## Go to top left corner and print date
echo -e "\e[H`date`\n"
## Add new datapoint to graph
if [ $right_to_left -eq 1 ]; then
val=$(echo $data | awk '{print $NF}')
data=$(echo $data $((val+=RANDOM%1000-500)) | cut -d' ' -f2-60)
else
val=$(echo $data | awk '{print $1}')
data=$(echo $((val+=RANDOM%1000-500)) $data | cut -d' ' -f1-59)
fi
## Draw graph and wait
graph 9 $data
sleep 1
done
Removing the final 'sleep' makes it more interresting

Oh and ofcourse some sample output of the test script:
Code:
Fri Jul 9 21:45:06 CEST 2010
101K | O | 101K
| OO |
| o OOOO |
| . . o oo. oOo..o. oOOOOO |
99K8 | O-OOo.----------.-------O.--------.OOoOOOOOOOOOOOO.OoOOOOOO | 99K8
| OOOOOOO. OOOo oOOOOO oOOOOOOOOOOOOOOOOOOOOOOOOO |
98K9 | OOOOOOOOO.o OOOOOo.OOOOOOOOoO .oOOOOOOOOOOOOOOOOOOOOOOOOOO | 98K9