Operating System - HP-UX
1826737 Members
2579 Online
109702 Solutions
New Discussion

Re: how to assing value in script

 
Jairo Campana
Trusted Contributor

how to assing value in script

Hi , i have a script , the results is a value numeric , this value is sent to a file
port 1 :0
port 5: 21
port 10: 5

I want assign to this value and the next time compare if change or increase for this port.

the port begin in 0.

for port 5: 21
the value compare is 21 , this port increase in X interval time .

a need the next time a need to know how much the value grows
legionx
3 REPLIES 3
Hein van den Heuvel
Honored Contributor

Re: how to assing value in script

Jairo,

That's a very confusing description. Please re-read.
But I think I know what you are getting at.

Does the data really sometimes have a space before the ':' and a space sometimes after it ?

Does each port appear every time?

Let's say you simply have an 'old' and a 'new' file. Each looks like your example, but no spaces around that ':'.

#cat old
port 1:0
port 5:21
port 10:5

#cat new
port 1:0
port 5:23
port 10:4

In order to 'subtract' those files, we need to remember the values of one of them.

We can do this in for example awk.

Before we start the real work, let's first try to get the data into an array and back in the BEGIN block for awk.

$ awk 'BEGIN {while (getline <"old"){split ($0,tmp,"[ :]");old[tmp[2]]=tmp[3]} for (port in old){print port "->" old[port]}}'
5->21
10->5
1->0

Yeah!
Now add reading the new file

$ cat port_diff.awk
BEGIN {
while (getline <"old"){
split ($0,tmp,"[ :]");
old[tmp[2]]=tmp[3]
}
}
{ split ($0,tmp,"[ :]");
new = tmp[3]
if (tmp[2] in old) {
o = old[tmp[2]];
x = "";
} else {
o = 0;
x = " New!"
}
printf ("port %2d : %4d %4s\n", tmp[2], new, (o==new)? "" : new - o);
}

$ awk -f port_diff.awk new
port 1 : 0
port 5 : 23 2
port 10 : 4 -1

Yeah Yeah!

All that is needed now is a script to get old an new done right.
Outline:

touch new
while true
do
mv new old
my-tool > new
awk -f port_diff.awk new
sleep 10
done


But wait... there is more...

It sounds like you have control over the data generation. Correct?

Might I recomment an XML format, or something readily parseable for example SCV file with a line per report period:

time,port#:value,port#:value,...
Data example
22:10:02,1:0,5:21,10:5
22:20:02,1:0,5:23,10:4

or if ports are a tight range 0..X
time,value0,value1,value2,...

Now lets assume the application does an append to the data file for each cycle.
Idealy it would time-stamp it, but lets just use a line with ----- as seperator.
for example:

#cat data
port 1:0
port 5:21
port 10:5
-----
port 1:0
port 5:20
port 10:15
-----
port 1:2
port 5:15
port 10:25
-----
port 1:3
port 5:21
port 10:35
-----
port 1:5
port 5:21
port 10:35
-----

Now let's tackle this with perl:

#cat port_diff.pl
use strict;
use warnings;
my ($old, $new, $tmp, $port, %data_1, %data_2);
$old = \%data_1; # Array reference
$new = \%data_2;
while (<>) { # process input

s/\s//g; # strip whitespace

$$new{$1} = $2 if (/port(\d+):(\d+)/) ; # portNN:NN

if (m|-*.*-|m) { # seperator line?
foreach $port (sort {$a <=> $b} keys %$old) {
my $n = $$new{$port};
my $o = $$old{$port};
printf "port %2d %4d %4s\n", $port, $n, ($n==$o)? '': $n-$o;
}
print qq(\n);
$tmp = $old; # old shall be new and new shall be old.
$old = $new;
$new = $tmp;
next
}
}

#perl port_diff.pl data


port 1 0
port 5 20 -1
port 10 15 10

port 1 2 2
port 5 15 -5
port 10 25 10

port 1 3 1
port 5 21 6
port 10 35 10

port 1 5 2
port 5 21
port 10 35

yeah yeah yeah!

So this perl uses two arrays data-1 and data-2 which are 'flipped' every time we read a chunk of data when a line of dashes is seen.
Btw.. normal folks would use if /----/ for that match.
And real tight programmers would use /^-+$/
:-)

When a data line is matched, we add an element to the data array pointed to by $new, using the port as key, value as data.

When that seperator line is seen, we retrieve the ports which are the keys for the data array pointed to by $old and sort them numerically with an inline function { $a <=> $ b }. Then we pick up the old and new values in variables (optional... just reads and writes easier).
And print the port, data and difference.

I could have used the use the keys for %$new. That's mcuh the same, except for the first dta chunk for which there are no old values yet. because they not exist for the first data chunk. We could also pretend there is a non-existent initial chunk with all port values 0.
That code could look like:
:
foreach $port (sort {$a <=> $b} keys %$new) {
my $n = $$new{$port};
my $o = $$old{$port};
$o = 0 unless $o;
:

And the output will start with:

port 1 0
port 5 21 21
port 10 5 5


'nuff for 1 lesson!
More over... my beer bottle is empty... you owe me one.

hth,
Hein.

Jairo Campana
Trusted Contributor

Re: how to assing value in script

this is my script , I modified the line awk of james.

#!/usr/bin/sh
clear
for i in `cat switchs|awk '{print $1}'`
do
echo "Connecting $i...."
#echo "statsclear"
FLG=0
while [ $FLG -le 60 ] #600
do
(sleep 1;echo admin;sleep 1 ;echo password;sleep 1 ;echo "statsclear" ;echo "porterrshow" ;sleep 2
"exit")|telnet $i > /frames/logcrc
awk 'NR>13 {if ($5~/k/) {F1=$5*1024} else {F12=$5};SUM+=F12;if (F12>0) {print
$1,$5}};END{print "TOTAL CRCERROR", SUM}' /frames/logcrc > /frames/logcrc.1
FLG=`expr $FLG + 1`
sleep 1 #300
done
done
legionx
Jairo Campana
Trusted Contributor

Re: how to assing value in script

the ouput in my sccript is of each switch porterrshow, before make one statsclear

233: 1
TOTAL CRCERROR 1
legionx