Retrieving random numbers out of a text file

Hi one and all,

I'm working on a Bash script that is designed to calculate how much IP traffic has passed through a port to determine traffic volume over a given amount of time.

I've currently been able to use the netstat -s command coupled with grep to write to a file the total packets received and I can't figure out how to use these numbers in a script to perform mathematical functions between them.

netstat -s > /home/nistleloy/Documents/datafile | grep 'total packets received' /home/nistleloy/Documents/datafile >> /home/nistleloy/Documents/tempIP

These are the numbers I've obtained:

nistleloy@****:~/Documents> cat tempIP
    6643 total packets received
    6718 total packets received
    7293 total packets received
    7785 total packets received

So with these numbers I want to use them in a script that subtracts the first reading from the second and the third reading from the fourth - bearing in mind that these numbers could be any size, any length everytime I run the netstat -s cmd.

Will I have to make each line unique so i can grep out just the actual numbers? (How would I do that with physically modifying the txt file).

Any pointers and/or suggestions welcome.

Try this on when catting your tmpfile. This would only work if there is spaces before the numbers in your tmpfile, as it looks like there are.

cat tempIP | tr -s " " | cut -d " " -f2

try this...

netstat -s|awk -F"[\t ]" '{print $2}'

Great stuff guys, thank you for that.

I hate to tap your brains again but here goes:

Now that I have just the numbers displayed within the file is there anyway I can call upon the numbers in a script so I can perform the workings out on them?

What i'm trying to achieve to get is the difference between the readings:

1st reading - 2nd reading
3rd reading - 4th reading

but I'm not sure on how to get these random numbers into a script.

I have a few thoughts:

Should I turn them into variables within the file and then use the variables in my script

ie edit the text file from my script and turn each number into a variable, so it'll look something like this:

nistleloy@****:~/Documents> cat tempIP
r1=6643
r2=6718
r3=7293
r4=7785

then call upon them in my script to do the maths - how would I assign the varibles within my script and how do I get these variables into my script?

OR:

is there a way to select line 1 from the file and make it a variable in my script then line 2 etc (remembering that these numbers are random so "greping" will not work).

Regards

$ cat tempIP
    6643 total packets received
    6718 total packets received
    7293 total packets received
    7785 total packets received
nawk 'FNR%2 {o=$1;next} {printf("%d - %d = %d\n", o, $1, o-$1)}' tempIP

If you get the numbers by themselves in a file, you can do the below to set them to variables.

COUNT=0
for num in `cat tmpfile2`
do
  COUNT=`expr $COUNT + 1`
  eval r${COUNT}=$num
done

echo "$r1 $r2 $r3 $r4"

Thank you.

That's perfect for my script. I've been bashing my head for a week over this! I can get on with other things now.

Thanks for all replies

Cheers

Hi, here's some ideas applied to Your data... assuming (including any number of space):

    6643 total packets received
    6718 total packets received
    7293 total packets received
    7785 total packets received

The first example is a method I use a lot in different versions, basically presenting the diff in a value from it's previous value. Good for analysing data from log files for example. And since there is always a beginning for everything, I chose in this case, 0:

#!/bin/bash
cnt=0
oldval=0
while read newval x y z; do
	echo diff=$((newval-oldval))
	oldval=$newval
	((cnt++))
done < tmpIP 

And if You want only diff from every other line (if this is what You meant):

#!/bin/bash
cnt=0
while read newval x y z; do
	[ $((cnt % 2)) -eq 1 ] && echo diff=$((newval-oldval))
	oldval=$newval
	((cnt++))
done < tmpIP 

Try changing [ $((cnt % 2)) -eq 1 ] for a different result. It's a construct to return true if You are on an even line. Well, er... yes, it's uneven with regard to cnt, but we usually we start counting from 0, so, oh, whatever... fiddle about with it! Change -eq to 0 for a different, "shifted", result.
The x y z is just to consume values from tmpIP file, otherwise the whole line would be considered one variable.
The read is good for ignoring whitespace, as many other clu's are.

Well, just my 2 �re!

/Lakris

PS Oh, almost forgot... maybe You could consider piping Your data collecting directly through the while loop, and not using intermediate files. Just a thought.

Thanks Lakris.

Currently I have my data collecting running through a function so every time the script is ran another piece of data is collected. The idea is that using chmod the script is ran x amount times between set intervals so I can determine network usage on a machine. Hence the working out of the differences between the values as demonstrated in your 2nd code.

To pipe into the while loop I would have to run the netstat -s command, followed by the grep to pick out the data I wanted (this case IP total packets received). Would I then need to put that data into a file to be stored, so I can then use it in the while loop - bearing in mind that this data could be collected over a 24hr period.

So I've been building the script to collect the data first then perform the calculations.
For instance:

collect_function  #Collect new data and put it in tempIP file 
cnt=0
while read newval x y z; do
        [ $((cnt % 2)) -eq 1 ] && echo diff=$((newval-oldval))
        oldval=$newval
        ((cnt++))
done < tempIP > tempdiff

I'm not sure how piping into the loop would work with collecting the data

Thanks for your input

Ok, I noticed that You are appending output, and if this is going on for some time, maybe You want some kind of average? With distinct time steps? For each time the data collection has taken place? It's hard to guess what the relevant analysis of the data would be.

Find max? min? Average? Time series? Related to time of day? There's lots of tools doing this, such as ntop and xosview. Mostly real time. They rely on data found in files in /proc/net, a part of the file system that is continuously updated with network related data (snapshots).

For example, I have a "system icon" in my IceWM that monitors network usage contiuously. It graphs usage in its icon. When I hover the mouse pointer over it it displays statistics about in/out, current, average, etc. I can't find it now but I'm pretty certain that that data is in one of the files in /proc/net.

Google for it. You may have better luck going for the source (netstat is also using /proc/net) and accumulating data from that, rather than creating logic around miscellaneous shell programming.

I am sorry if I can't give any better directions, I think I will explore this tomorrow...

/Lakris

The analysis I'm trying to come out with is to determine over a given amount of time when network usage is low. So theoretically over say 10, 30 minute time-slots I can see which time-slot is on average the best time-slot to start a data backup.

I envisage a file that can be interrogated about all the collected time-slots network usage and work out each time-slots average and say "time slot" x is on average the best time to perform a backup of a system. The time-slots time, that is on average the lowest network usage, is then put into a backup system (AMANDA) to perform the backup. The time-slots are related to time of day.

Just explored the /proc/net/dev file which produces this result
Edited for space and format reasons.

 
 nistleloy@****:/proc/net> cat dev 
 Inter- face   |      Receive                         |           Transmit 
                  bytes        packets                  bytes        packets    
     lo:            2260          38                      2260         38
   eth1:           6288256      4939                  351334       3370   

Looking at that information this would be more clinical and create a more manageable analysis of network usage compared to working individual protocols out. Now all I have need to do is run the data collection based on the total transmit / receive data. I'd probably use the packet data.

Great spot Lakris.

I also looked at the two tools you pointed out and they will interrogate this information to. Ironically the netstat -s command does not provide the succinct information that /pro/net/dev does. Furthermore looking at XP netstat command this info does come back! Just looking around that dir and I think netstat basis it's info on proc/net/protocols amongst over things hence why when I was trying to code with the command I was gathering small bits of data and building them up logically.

Just had a look around my system apps and found "Network tool" that shows the interface stats gathered from the above file. Although it doesn't display any graphs just neatly presented numbers for each interface.

Once again thank you for your input.

Np! :slight_smile:

After running this script

cnt=0
while read newval x y z; do
        echo $((newval-oldval))
        oldval=$newval
        ((cnt++))
done < dump2 > final

on this file with these numbers:

nistleloy@****:~/Documents> cat dump2
84657
93406
112554
112607
123780
254687

i get this answer back:

nistleloy@****:~/Documents> cat final
84657
8749
19148
53
11173
130907

Is there anyway of stopping the the first reading in dump2 file being subtracted from 0 and ending up in the final file as it's really messing up the results! I far as I can see it shouldn't perform any maths on that reading at all but it is.

Thanks for any tips/advice.

Hi, You could use something like
[ $cnt -gt 0 ] && echo ...
as the first statement in loop.

/Lakris