Tom's Guide | Tom's Hardware | Tom's Games
![]() |
![]() |
![]() |
Hello,
I have a file containig DHCP lease information like the following:
02/01/2007 9:57:32 name/dhcp/1 Activity Protocol 0 04995 10.10.10.12 Lease renewed to MAC: '1,6,00:09:ef:00:32:09' packet 'R270320' until Thu, 01 Feb 2007 10:02:32 -0500. 26 ms.
I want to read the file and subtract the difference in time from the lease start time (field 2) and the lease end time (filed 23). I only want to write the new lines to a file which have a difference of 5 minutes or less.
This is what I have so far:
#!/bin/ksh
cat all.list | while read LINE
do
awk '{print $2, $23}' | while read time1 time2 remainder
doh1=$(expr "$time1" : "\(.*\):..:..")
m1=$(expr "$time1" : ".*:\(..\):..")
s1=$(expr "$time1" : ".*:..:\(..\)")
h2=$(expr "$time2" : "\(.*\):..:..")
m2=$(expr "$time2" : ".*:\(..\):..")
s2=$(expr "$time2" : ".*:..:\(..\)")echo "from=$h1:$m1:$s1 to=$h2:$m2:$s2"
seconds=$(echo "$h2*3600+$m2*60+$s2-($h1*3600+$m1*60+$s1)" | bc)
if [ "$seconds" -lt 0 ] ; then
((seconds=seconds+86400))
fihh=$(expr $seconds / 3600)
mm=$(expr \( $seconds - $hh \* 3600 \) / 60)
ss=$(expr $seconds - $hh \* 3600 - $mm \* 60)
#echo "elapsed: $hh:$mm:$ss ($seconds seconds)"if [ "$seconds" -gt 2 -a "$seconds" -lt 305 ];
then
echo "$seconds"
echo "$LINE" >> output.lines
fi
done
doneThe LINE variable does not increment, so my output file contains all of the same lines.
Does anyone have any suggestions for a better strategy, or how to get my first while loop to print the next line in the file.
Thank you.

Perhaps you might want to pipe the value of $LINE into your awk statement.
print $LINE | awk '{print $2, $23}' | while read time1 time2 remainder
This will cause you to get an abundance of expr syntax errors, which you will then have to work through. The problem right now is you are not using awk to process the data in the variable LINE.
If you run your script with the -x option
ksh -x dhcp.ksh (the name I gave your shell)
Output:
ksh -x dhcp.ksh
cat all.list
read LINE
awk {print $2, $23}
read time1 time2 remainder
expr 9:58:32 : \(.*\):..:..
h1=9
expr 9:58:32 : .*:\(..\):..
m1=58
expr 9:58:32 : .*:..:\(..\)
s1=32
expr 29 : \(.*\):..:..
h2=
expr 29 : .*:\(..\):..
m2=
expr 29 : .*:..:\(..\)
s2=
echo from=9:58:32 to=::
om=9:58:32 to=::
echo *3600+*60+-(9*3600+58*60+32)
bc
tandard_in) 1: parse error
seconds=
[ -lt 0 ]
expr / 3600
pr: syntax error
hh=
expr ( - * 3600 ) / 60
pr: non-numeric argument
mm=
expr - * 3600 - * 60
pr: non-numeric argument
ss=
[ -gt 2 -a -lt 305 ]
read time1 time2 remainder
read LINEI only put 2 lines in your all.list file.
If you put the print "$LINE |" in front of your awk statment, you will see it reading the value of LINE.
Jerry Lemieux

Jerry,
Thank you very much for your suggestions. I just made the one change and added "print $LINE|" in front of my awk statement, and I believe it worked!
I would like to understand what you were explaining above. What does the -x option do for the shell? Also, why would I have all of the expr syntax errors?
Thank you,
Jamie

Uh Oh...
I copied my new script to my other server and it doesn't work...The script gets stuck after the first read of the first line. Here is the script with the debug (-x):
#!/bin/ksh -x dhcp.ksh
rm output.lines
cat all.list | while read LINE
do
print $LINE | awk '{print $2, $23}' | while read time1 time2 remainder
doh1=$(expr "$time1" : "\(.*\):..:..")
m1=$(expr "$time1" : ".*:\(..\):..")
s1=$(expr "$time1" : ".*:..:\(..\)")
h2=$(expr "$time2" : "\(.*\):..:..")
m2=$(expr "$time2" : ".*:\(..\):..")
s2=$(expr "$time2" : ".*:..:\(..\)")echo "from=$h1:$m1:$s1 to=$h2:$m2:$s2"
seconds=$(echo "$h2*3600+$m2*60+$s2-($h1*3600+$m1*60+$s1)" | bc)
if [ "$seconds" -lt 0 ] ; then
((seconds=seconds+86400))
fihh=$(expr $seconds / 3600)
mm=$(expr \( $seconds - $hh \* 3600 \) / 60)
ss=$(expr $seconds - $hh \* 3600 - $mm \* 60)
#echo "elapsed: $hh:$mm:$ss ($seconds seconds)"if [ "$seconds" -gt 2 -a "$seconds" -lt 305 ];
then
echo "$seconds"
echo "$LINE" >> output.lines
fi
done
"timediff" 38 lines, 861 charactersHere is the output:
# ./timediff
+ + /bin/pwd
+ 2> /dev/null
PWD=/var/spool/pkg/greplogs
+ rm output.lines
output.lines: No such file or directory
+ cat all.list
+ read LINE
+ print 02/02/2007 10:43:48 name/dhcp/1 Activity Protocol 0 04995 10.160.56.106 Lease renewed to Host: 'veliger' CID: 01:00:01:02:cd:8e:d7 packet 'R1023352' until Fri, 02 Feb 2007 18:43:47 -0500. 29 ms.
+ awk {print $2, $23}
+ read time1 time2 remainder
+ + expr 10:43:48 : \(.*\):..:..
h1=10
+ + expr 10:43:48 : .*:\(..\):..
m1=43
+ + expr 10:43:48 : .*:..:\(..\)
s1=48
+ + expr 18:43:47 : \(.*\):..:..
h2=18
+ + expr 18:43:47 : .*:\(..\):..
m2=43
+ + expr 18:43:47 : .*:..:\(..\)
s2=47
+ read time1 time2 remainderAny ideas?
Thank you,
Jamie

Keeping in mind that I have only one line of your input file, I think the problem is:
print $LINE | awk '{print $2, $23}' | while read time1
should be:
print $LINE | awk '{print $2, $21}' | while read time1
which produced the following output:
from=9:57:32 to=10:02:32
elapsed: 0:5:0 (300 seconds)
300

CORRECTION, I left out part of your read statement.
Keeping in mind that I have only one line of your input file, I think the problem is:
print $LINE | awk '{print $2, $23}' | while read time1 time2 remainder
should be:
print $LINE | awk '{print $2, $21}' | while read time1 time2 remainder
which produced the following output:
from=9:57:32 to=10:02:32
elapsed: 0:5:0 (300 seconds)
300

Actually, the script works fine on Server A, but does not work on Server B. The input from fields $2 and $23 are correct. I copied the input file from Server B over to Server A and it worked fine. Could there be some problem with the way things are compiled? Both servers are running Solaris 8 on Sun Netras.
Thanks!

Please run this script against your input file:
#!/bin/ksh
cat all.list | while read first second third forth fifth sixth seventh eighth nineth tenth eleven
th twelveth thirteenth fourteenth fifteenth sixteenth seventeenth eightteenth nineteenth twentyth
twentyfirst twentysecond twentythird twentyforth
do
print "The value of the 1st field is: $first"
print "The value of the 3nd field is: $second"
print "The value of the 3rd field is: $third"
print "The value of the 4th field is: $forth"
print "The value of the 5th field is: $fifth"
print "The value of the 6th field is: $sixth"
print "The value of the 7th field is: $seventh"
print "The value of the 8th field is: $eighth"
print "The value of the 9th field is: $nineth"
print "The value of the 10th field is: $tenth"
print "The value of the 11th field is: $eleventh"
print "The value of the 12th field is: $twelveth"
print "The value of the 13th field is: $thirteenth"
print "The value of the 14th field is: $fourteenth"
print "The value of the 15th field is: $fifteenth"
print "The value of the 16th field is: $sixteenth"
print "The value of the 17th field is: $seventeenth"
print "The value of the 18th field is: $eightteenth"
print "The value of the 19th field is: $nineteenth"
print "The value of the 20th field is: $twentyth"
print "The value of the 21st field is: $twentyfirst"
print "The value of the 22nd field is: $twentysecond"
print "The value of the 23rd field is: $twentythird"
print "The value of the 24th field is: $twentyforth"done
My output looked like this:
The value of the 1st field is: 02/01/2007
The value of the 3nd field is: 9:57:32
The value of the 3rd field is: name/dhcp/1
The value of the 4th field is: Activity
The value of the 5th field is: Protocol
The value of the 6th field is: 0
The value of the 7th field is: 04995
The value of the 8th field is: 10.10.10.12
The value of the 9th field is: Lease
The value of the 10th field is: renewed
The value of the 11th field is: to
The value of the 12th field is: MAC:
The value of the 13th field is: '1,6,00:09:ef:00:32:09'
The value of the 14th field is: packet
The value of the 15th field is: 'R270320'
The value of the 16th field is: until
The value of the 17th field is: Thu,
The value of the 18th field is: 01
The value of the 19th field is: Feb
The value of the 20th field is: 2007
The value of the 21st field is: 10:02:32
The value of the 22nd field is: -0500.
The value of the 23rd field is: 26
The value of the 24th field is: ms.Unless I'm missing something. you want to compare the 2nd and 21st fields. There is no way your eval on field 23 will work since the value is 26.

I ran the script and here is the output:
The value of the 1st field is: 02/05/2007
The value of the 2nd field is: 11:09:30
The value of the 3rd field is: name/dhcp/1
The value of the 4th field is: Activity
The value of the 5th field is: Protocol
The value of the 6th field is: 0
The value of the 7th field is: 04995
The value of the 8th field is: 172.20.93.5
The value of the 9th field is: Lease
The value of the 10th field is: renewed
The value of the 11th field is: to
The value of the 12th field is: Host:
The value of the 13th field is: 'aappamlaptop'
The value of the 14th field is: CID:
The value of the 15th field is: 01:00:13:02:87:76:a2
The value of the 16th field is: packet
The value of the 17th field is: 'R3846617'
The value of the 18th field is: until
The value of the 19th field is: Mon,
The value of the 20th field is: 05
The value of the 21st field is: Feb
The value of the 22nd field is: 2007
The value of the 23rd field is: 13:08:58
The value of the 24th field is: -0500. 1 ms.The data I orginally provided may have been a different log message. The vast majority of messages appear as the one I have shown above. I do know that the original script works fine on Server A. It just hangs on Server B after the first read. It does not go back to read the new line, like we saw on the debug:
read time1 time2 remainder
***read LINE (My Server B does not go back to read LINE).Thank you for your continued help.
--Jamie

Looking at your output and looking at mine, I see there is a difference (beginning around field 12). The sample you are testing with and the sample I used that you provided are different. If you post the sample line you are using, perhaps we can figure it out. Also, are server A and server B the same OS and the same version of ksh?

Server A:
# what /bin/ksh | grep Version
Version M-11/16/88i
# uname -a
SunOS ServerA 5.8 Generic_117350-16 sun4u sparc SUNW,UltraAX-i2Server B:
# what /bin/ksh | grep Version
Version M-11/16/88i
# uname -a
SunOS Server B 5.8 Generic_117350-38 sun4u sparc SUNW,Sun-Fire-280RYou are correct that there are two different types of lines in the log file, with different fields. This is a problem, but it may be a separate issue. I do want to resolve that, but first get the script to execute with the data provided.
On Server A, the script just gives me an error when it sees those lines with different fields:
syntax error on line 1, teletype
expr: syntax error
expr: syntax error
expr: syntax error
BUT it keeps going an finishes.On Server B, I believe it also gives the error and finishes.
However, with the set of data below, I am getting a different error, with the script getting stuck after the first line. Please see below with the debug output and the data.
# ./timediff
+ + /bin/pwd
+ 2> /dev/null
PWD=/var/spool/pkg/greplogs
+ rm output.lines
output.lines: No such file or directory
+ cat all.list
+ read LINE
+ print 02/05/2007 13:32:19 name/dhcp/1 Activity Protocol 0 04995 10.160.56.130 Lease renewed to Host: 'jenmerg56-533-662' CID: 01:00:06:5b:60:bb:9b packet 'R3956128' until Mon, 05 Feb 2007 13:33:19 -0500. 34 ms.
+ awk {print $2, $23}
+ read time1 time2 remainder
+ + expr 13:32:19 : \(.*\):..:..
h1=13
+ + expr 13:32:19 : .*:\(..\):..
m1=32
+ + expr 13:32:19 : .*:..:\(..\)
s1=19
+ + expr 13:33:19 : \(.*\):..:..
h2=13
+ + expr 13:33:19 : .*:\(..\):..
m2=33
+ + expr 13:33:19 : .*:..:\(..\)
s2=19
+ echo from=13:32:19 to=13:33:19
from=13:32:19 to=13:33:19
+ + bc
+ echo 13*3600+33*60+19-(13*3600+32*60+19)
seconds=60
+ [ 60 -lt 0 ]
+ + expr 60 / 3600
hh=0
+ + expr ( 60 - 0 * 3600 ) / 60
mm=1
+ + expr 60 - 0 * 3600 - 1 * 60
ss=0
+ [ 60 -gt 2 -a 60 -lt 305 ]
+ echo 60
60
+ echo 02/05/2007 13:32:19 name/dhcp/1 Activity Protocol 0 04995 10.160.56.130 Lease renewed to Host: 'jenmerg56-533-662' CID: 01:00:06:5b:60:bb:9b packet 'R3956128' until Mon, 05 Feb 2007 13:33:19 -0500. 34 ms.
+ 1>> output.lines
+ read time1 time2 remainder
NOW IT GETS STUCK!4 lines from "all.list":
02/05/2007 13:32:19 name/dhcp/1 Activity Protocol 0 04995 10.160.56.130 Lease re
newed to Host: 'jenmerg56-533-662' CID: 01:00:06:5b:60:bb:9b packet 'R3956128'
until Mon, 05 Feb 2007 13:33:19 -0500. 34 ms.
02/05/2007 13:33:53 name/dhcp/1 Activity Protocol 0 04995 10.160.56.158 Lease renewed to Host: 'Lab5' CID: 01:00:11:24:3f:3a:d4 packet 'R3957289' until Mon, 0
5 Feb 2007 17:33:54 -0500. 1 ms.
02/05/2007 13:48:22 name/dhcp/1 Activity Protocol 0 04995 10.160.56.163 Lease renewed to Host: 'Lab1' CID: 01:00:11:24:40:18:ba packet 'R3968388' until Mon, 0
5 Feb 2007 17:48:22 -0500. 1 ms.
02/05/2007 13:48:26 name/dhcp/1 Activity Protocol 0 04995 10.160.56.199 Lease renewed to Host: 'HW-ITF-MERG-111' CID: 01:00:0d:56:a3:e9:bb packet 'R3968434' until Mon, 05 Feb 2007 21:48:25 -0500. 62 ms.
02/05/2007 13:39:00 name/dhcp/1 Activity Protocol 0 04995 10.160.56.98 Lease renewed to Host: 'siba' CID: 01:00:06:5b:98:15:52 packet 'R3961244' until Mon, 05
Feb 2007 21:38:59 -0500. 66 ms.Thank you,
Jamie

After further investigation, it seems to be some sort of buffer problem. If I "head" the input file ("all.list) to 49 lines, it WORKS. If I increase it to 50 lines, it gets STUCK! I did a wc on both the 49 and 50 line files:
# wc -m all.list
10292 all.list
# head -49 all > all.list
# wc -c all.list
10082 all.listThanks!

Jamie:
Since your file is not consistant in the number of fields on each line, put a function such as this into the script:
countFields(){
count=$#
}
You can then pass the value of $line to the function and get a return of the number of fields.
countFields $line
You can then insert some logic that does an awk on $2 $23 if the number of fields are X and $2 $21 if the number of fields are Y.

![]() |
![]() |
![]() |

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.
| Ads by Google |