The UNIX and Linux Forums  

Go Back   The UNIX and Linux Forums > Top Forums > Shell Programming and Scripting
Google UNIX.COM


Shell Programming and Scripting Post questions about KSH, CSH, SH, BASH, PERL, PHP, SED, AWK and OTHER shell scripts here.

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
Get date and time for past 1 hour from current date spch2o Shell Programming and Scripting 5 08-29-2008 01:32 AM
Processing a log file based on date/time input and the date/time on the log file primp Shell Programming and Scripting 4 03-16-2008 08:23 AM
String manupulations... cutelucks Shell Programming and Scripting 2 11-24-2007 12:18 AM
Date/Time help ssmiths001 Shell Programming and Scripting 5 01-27-2006 12:40 AM
date and time ker UNIX for Dummies Questions & Answers 3 11-07-2002 08:47 AM

Reply
 
Submit Tools LinkBack Thread Tools Search this Thread Display Modes
  #1  
Old 08-02-2005
Registered User
 

Join Date: Jul 2005
Posts: 57
Lightbulb Time & Date Manupulations

Hi friends ,
I have a long file having different fields like :-
F1 F2 YY/MM/DD hh:mm:ss seconds
XYZ PQR 05/06/25 14:15:56 120
XYZ PQR 05/06/28 00:18:36 12
XYZ PQR 05/06/29 23:12:36 1500
I want to subtract the yy/mm/dd in line 2 from yy/mm/dd in line 1 using DATECALC & hh:mm:ss in line(2) from hh:mm:ss in line(1) & compare the output of substraction (obtained in seconds) with the seconds in line(1) and echo whether it is greater than seconds(120). I want the process to repeat for the whole long file. I tried to modify the nawk script given by Vgersh99
according to my need but it did not worked (the script was working fine before adding yy/mm/dd field in the input file). The changes that I made in original script are Bolded.

BEGIN {
FStime=":"
multN=split("3600 60 1", mult, " ");
}
{
n=split($4, timeA, FStime)
time = 0
for(i=1; i <= n; i++)
time += timeA[i] * mult[i]
diff = $5
}
{
date = {printf ("20"substr($3,1,2)" "substr($3,4,2)" "substr($3,7,2)"\n" )}
}

FNR == 1 {
prevTime=time;
prevDiff=diff;
prevdate=date
next;
}
{
print $0 "\t", (((prevdate*8760 + time - prevTime)) > prevDiff ) ? " " : "S"
prevTime=time; prevDiff=diff;prevdate=`datecalc -a prevdate - date`
}

It gives error at line 13
bailing error at line 13
syntax error at line 22
<<< { >>>
Can u help me out.
Thanks in Advance.
Reply With Quote
Forum Sponsor
  #2  
Old 08-02-2005
Perderabo's Avatar
Unix Daemon
 

Join Date: Aug 2001
Location: Washington DC Area
Posts: 8,667
I don't understand what you're trying to do. The date in your second line is days after your first line. That will be hundreds of thousands of seconds which is nowhere near 120. You mention datecalc and then present an awk script. I see no datacalc.

But to subtract timestamps getting the result in seconds, try this...
Code:
#! /usr/bin/ksh

echo 05/06/25 14:15:56 | IFS=" /:" read Y1 M1 D1 h1 m1 s1
echo 05/06/28 00:18:36 | IFS=" /:" read Y2 M2 D2 h2 m2 s2
((Y1=Y1+2000))
((Y2=Y2+2000))
j1=$(datecalc -j $Y1 $M1 $D1)
j2=$(datecalc -j $Y2 $M2 $D2)
((j2=j2-j1))
((j1=j1-j1))
((secs1=((j1*24+h1)*60+m1)*60+s1))
((secs2=((j2*24+h2)*60+m2)*60+s2))
echo $((secs2-secs1))
exit 0
Reply With Quote
  #3  
Old 08-03-2005
Registered User
 

Join Date: Jul 2005
Posts: 57
Quote:
Originally Posted by Perderabo
I don't understand what you're trying to do. The date in your second line is days after your first line. That will be hundreds of thousands of seconds which is nowhere near 120. You mention datecalc and then present an awk script. I see no datacalc.

But to subtract timestamps getting the result in seconds, try this...
Code:
#! /usr/bin/ksh

echo 05/06/25 14:15:56 | IFS=" /:" read Y1 M1 D1 h1 m1 s1
echo 05/06/28 00:18:36 | IFS=" /:" read Y2 M2 D2 h2 m2 s2
((Y1=Y1+2000))
((Y2=Y2+2000))
j1=$(datecalc -j $Y1 $M1 $D1)
j2=$(datecalc -j $Y2 $M2 $D2)
((j2=j2-j1))
((j1=j1-j1))
((secs1=((j1*24+h1)*60+m1)*60+s1))
((secs2=((j2*24+h2)*60+m2)*60+s2))
echo $((secs2-secs1))
exit 0
Hi,
I know that the difference of two dates converted into seconds that will be hundreds of thousands of seconds which is nowhere near 120. But the requirement is such that I have to do it because there will be a small difference sometimes for example 2005/06/25 23:59:01-2005/06/26 00:00:05 gives 64 sec. Then simply subtracting time will give wrong results when date changes. The script originally given by vgersh99 was as under :

BEGIN {
split("3600 60 1", mult)
FS=":| "
}
{ time = 0
for (i=1; i < 4; i++)
time += $i * mult[i]
diff = $4
}
FNR == 1 {
prevTime = time
prevDiff = diff
next
}
{ print ( ( time - prevTime) > prevDiff ) ? "greater" : "notGreater"
prevTime=time; prevDiff=diff
}
for the problem :
I have a long file having different fields like :-
hh:mm:ss seconds
14:15:56 120
14:18:36 12
15:12:36 1500
I want to subtract the hh:mm:ss in line(2) from hh:mm:ss in line(1) & compare the output of substraction (obtained in seconds) with the seconds in line(1) and echo whether it is greater than seconds(120). I want the process to repeat for the whole file as in excel we copy the formula down the column.
Now the field of date has been incorporated in input file like that :
F1 F2 YY/MM/DD hh:mm:ss seconds
XYZ PQR 05/06/25 14:15:56 120
XYZ PQR 05/06/28 00:18:36 12
XYZ PQR 05/06/29 23:12:36 1500
The requirement of just to subtract the date also and the output difference in seconds to be added to the difference of time (in seconds) & then compare it with field 5 ie seconds column. I tried datecalc at the last line of script as above but it gave errors as given above. Please help me to improve the script not matter using datecalc or else.
Thanks in advance.
Reply With Quote
  #4  
Old 08-03-2005
vgersh99's Avatar
Moderator
 

Join Date: Feb 2005
Location: Boston, MA
Posts: 3,029
you can definitely do what you need with the 'datacalc' - I'll leave that as an exercise for the OP.

here's the modified version of the awk solution based on the modified sample input file.

nawk -f vanand.awk sample.txt
Code:
BEGIN {
   split("3600 60 1", mult)
   secINday=86400
   FS=":| "
}

# date to Julian
function date2julian(day, month, year,  _m, _y)
{
  _m=12 * year + month - 3
  _y= _m / 12
  return ( (734 * _m + 15) / 24 -  2 * _y + _y/4 - _y/100 + _y/400 + day + 1721119 )

}

# number of days in between 2 passed days
function dateDiff(t,f,   _tA,_fA) # $1 - TO year/month/day
                                           # $2 - FROM year/month/day
{
    split(t, _tA, "/")
    split(f, _fA, "/")
    return(  date2julian(_tA[3], _tA[2], _tA[1]) - date2julian(_fA[3], _fA[2], _fA[1]) )
}

{
  time = 0
  for (i=4; i < 7; i++)
    time += $i * mult[i-3]
  diff = $NF
  date = $3
}
FNR == 1 {
  prevTime = time
  prevDate = date
  prevDiff = diff
  next
}

{
  print ( ( time - prevTime + (dateDiff(date, prevDate) * secINday) ) > prevDiff ) ? "greater" : "notGreater"
  prevTime=time; prevDate=date; prevDiff=diff
}
Reply With Quote
  #5  
Old 08-04-2005
Registered User
 

Join Date: Jul 2005
Posts: 57
Hi Friend,
Thanks a lot for the script written by u. But it is giving some wrong results.
I have giving the output of the script applied to my file :
12345678 ABCDE 2004/09/01 13:38:15 000004 S
12345678 ABCDE 2004/09/01 14:37:08 000164
12345678 ABCDE 2004/09/01 16:13:08 000045 S
12345678 ABCDE 2004/09/01 16:15:15 000012 S
12345678 ABCDE 2004/09/01 16:15:46 000030 S
12345678 ABCDE 2004/09/01 16:22:38 000024 S
12345678 ABCDE 2004/09/01 17:26:02 000029 S
12345678 ABCDE 2004/09/01 18:49:11 001679
12345678 ABCDE 2004/09/01 21:53:22 000138 S
12345678 ABCDE 2004/09/02 10:41:13 000063 S
12345678 ABCDE 2004/09/02 11:02:26 000074 S
12345678 ABCDE 2004/09/02 20:12:09 000358
12345678 ABCDE 2004/09/02 20:18:42 001498 S
12345678 ABCDE 2004/09/03 10:07:34 000068 S
12345678 ABCDE 2004/09/03 10:18:16 000182 S
12345678 ABCDE 2004/09/03 10:51:47 000097 S
12345678 ABCDE 2004/09/03 11:07:15 000020 S
12345678 ABCDE 2004/09/03 11:08:15 000027 S
12345678 ABCDE 2004/09/03 11:15:18 000018 S
12345678 ABCDE 2004/09/03 11:18:50 000019 S
12345678 ABCDE 2004/09/03 12:14:18 000003
12345678 ABCDE 2004/09/03 13:51:24 000038 S
12345678 ABCDE 2004/09/03 18:37:36 000023
12345678 ABCDE 2004/09/03 18:38:43 000804 S
12345678 ABCDE 2004/09/03 18:56:15 000005 S
12345678 ABCDE 2004/09/03 18:56:37 001488 S
12345678 ABCDE 2004/09/04 07:15:01 000623 S
12345678 ABCDE 2004/09/04 07:32:29 000001 S
12345678 ABCDE 2004/09/04 10:20:36 000055 S
12345678 ABCDE 2004/09/04 11:06:58 000021 S
12345678 ABCDE 2004/09/04 12:53:11 000032 S
12345678 ABCDE 2004/09/04 13:03:14 000086 S
12345678 ABCDE 2004/09/04 14:19:00 000049
12345678 ABCDE 2004/09/04 14:31:59 000006 S
12345678 ABCDE 2004/09/04 14:32:12 000036 S
12345678 ABCDE 2004/09/04 21:30:19 000107
12345678 ABCDE 2004/09/05 10:06:37 000006 S
U can easily view that the difference between two times on same day & difference between two times on different day for consecutive lines giving wrong results of comparision.
Please Reconsider the script why it is giving errors. Script given was :
BEGIN {
split("3600 60 1", mult)
secINday=86400
FS=":| "
}

# date to Julian
function date2julian(day, month, year, _m, _y)
{
_m=12 * year + month - 3
_y= _m / 12
return ( (734 * _m + 15) / 24 - 2 * _y + _y/4 - _y/100 + _y/400 + day + 1721119 )

}

# number of days in between 2 passed days
function dateDiff(t,f, _tA,_fA) # $1 - TO year/month/day
# $2 - FROM year/month/day
{
split(t, _tA, "/")
split(f, _fA, "/")
return( date2julian(_tA[3], _tA[2], _tA[1]) - date2julian(_fA[3], _fA[2], _fA[1]) )
}

{
time = 0
for (i=4; i < 7; i++)
time += $i * mult[i-3]
diff = $NF
date = $3
}
FNR == 1 {
prevTime = time
prevDate = date
prevDiff = diff
next
}

{
print $0 "\t",( ( time - prevTime + (dateDiff(date, prevDate) * secINday) ) > prevDiff ) ? " " : "S"
prevTime=time; prevDate=date; prevDiff=diff
}
Thanks in advance for kind assistance.
Reply With Quote
  #6  
Old 08-04-2005
vgersh99's Avatar
Moderator
 

Join Date: Feb 2005
Location: Boston, MA
Posts: 3,029
the file you've just posted is NOT in the same format posted previously.
change:
diff = $NF
to
diff = $7
Reply With Quote
  #7  
Old 08-05-2005
Registered User
 

Join Date: Jul 2005
Posts: 57
Hi Friend
Thanks for the tip. But $NF or $7 does not matter both are same in this script. The reason behind wrong results was formatting of fields{pl see point (2)}.
I made several observation on running the script as under :
1) The script gives wrong difference between two dates when month changes ex: 2005/05/01-2005/04/30 gave 1.43687
2005/06/01-2005/05/31 gave 0.436875
Due to which the script gives comparision wrong results at month changing.
2) The script is running well (except above problem) for the input file when the fields are spaced equally like-
"12345678 ABCDE 2005/06/21 18:11:36 120"
but when the input file is like "12345678 AB 2005/06/01 18:11:36 120" it gives totally wrong results. However if I changes it to
"12345678 AB 2005/06/01 18:11:36 120" then results are again right. Whether unequal spacing can make a lot of difference.
I want to know what changes shd I made to script to overcome both problems.
Please help me out. Thanks
Reply With Quote
Google The UNIX and Linux Forums
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes




All times are GMT -7. The time now is 05:13 AM.


Powered by: vBulletin, Copyright ©2000 - 2006, Jelsoft Enterprises Limited.
The UNIX and Linux Forums Content Copyright ©1993-2008. All Rights Reserved.Ad Management by RedTyger Visit The Complex Event Processing Blog

Content Relevant URLs by vBSEO 3.2.0