I have the following table below. I will be referencing a specific number based on other extraneous information. Lets say the specific number is 30. I first need to count 30 numbers down my September list then move to October then November until count has reached 30. Then I need to count all the missing values until the next value would reach the 30th count from the previous task. So for this example the 30th number would be November 19th. The count of the missing should be 55, November 15th (if I counted that right). That value would then be stored in a cell.
I obtained the missed days with the following formula: =IFERROR(SMALL(IF(ISERROR(MATCH(ROW(L$1:INDEX(L:L,N$2)),M$2:INDEX(M:M,COUNT(M:M)+ROW(M$1)),0)),ROW(L$1:INDEX(L:L,N$2))),ROW()-ROW(L$1)),"") (see table 2 for column reference)
The max column value will be blank if there is no data in the month column, therefore the missed column will also have not data. I set that up with the following formula:
=IF(COUNTA(M:M)>1,31,"") (see table 2 for column reference)
Table 1
September max missed October max missed November max missed
1 30 4 1 31 2 2 30 1
2 6 3 6 7 3
3 7 4 7 9 4
5 11 5 8 10 5
8 12 12 9 11 6
9 13 15 10 16 8
10 14 20 11 17 12
15 16 28 13 18 13
22 17 30 14 19 14
23 18 31 16 20 15
24 19 17 22 21
25 20 18 27 23
29 21 19 28 24
26 21 25
27 22 26
28 23 29
30 24 30
25
26
27
29
Table 2
L M N O
(blank) September max missed
I have an idea of how I would write this, but do not know the syntax:
x = Select(Range("G8").Value)
'value that holds specific value (30 for above example)
If x < 31 Then
'30 days in September
y = Count(M2:M32) Until = x
'values in September
z = Count(O2:O32) Until = value of y - 1
'What if the last value is the 30th of September, how would you stop on August 31st?
Range("A1").Value = z
'value of z is stored in cell A1
Elseif x < 62 Then
'61 days in September and October
y2 = Count(M2:M32) & Count(Q2:Q32) Until = x
'Values in September and October
z2 = Count(R2:R32) & (S2:S32) Until =value of -1
'Again, if the last value is the 31st of October how would you stop on September 30th?
Range("A1").Value = z
'Value of z is stored in cell A1
Elseif
'continue for each month (12 times)
End If
There are a couple of things that could cause some problems here with my suggestions (that I just thought of). How would I dictate my starting month? Lets say I wanted to reference a specific cell and that cell contains the number 4. So I would want to start in April, even if I had data in March. Another way of thinking about this is March is in year 2019 and April is in 2018. So then how could I could I get the code to jump from say December back to January? Say column Z is December and column A is January. I wouldn't necessarily want my code to only read left to right. It would need to start in reference to another cell and then jump back to the start if the year changes.
I apologies for the lengthiness, but that's my best effort in explaining. Let me know if you have any questions or if I can provide anyone with more example, pictures, etc.
I think you should reorganize your data table to something like this:
Day Status
01.09.2018 ok
02.09.2018 ok
03.09.2018 ok
04.09.2018 missed
05.09.2018 ok
06.09.2018 missed
07.09.2018 missed
08.09.2018 ok
09.09.2018 ok
10.09.2018 ok
11.09.2018 missed
12.09.2018 missed
13.09.2018 missed
14.09.2018 missed
15.09.2018 ok
16.09.2018 missed
17.09.2018 missed
18.09.2018 missed
19.09.2018 missed
20.09.2018 missed
21.09.2018 missed
22.09.2018 ok
23.09.2018 ok
24.09.2018 ok
25.09.2018 ok
26.09.2018 missed
27.09.2018 missed
28.09.2018 missed
29.09.2018 ok
30.09.2018 missed
01.10.2018 ok
02.10.2018 ok
03.10.2018 ok
04.10.2018 ok
05.10.2018 ok
06.10.2018 ok
07.10.2018 ok
08.10.2018 ok
09.10.2018 ok
10.10.2018 ok
11.10.2018 ok
12.10.2018 ok
13.10.2018 ok
14.10.2018 ok
15.10.2018 ok
16.10.2018 ok
17.10.2018 ok
18.10.2018 ok
19.10.2018 ok
20.10.2018 ok
21.10.2018 ok
22.10.2018 ok
23.10.2018 ok
24.10.2018 ok
25.10.2018 ok
26.10.2018 ok
27.10.2018 ok
28.10.2018 ok
29.10.2018 ok
30.10.2018 ok
31.10.2018 missed
After that, you could easily manage your counts, find anything you want via filtering, specifying date start and so on
I have a log file that shows switch time between my scripts:
Tue Oct 24 11:57:54 IRST 2017 Script switched from abc to XYZ
Tue Oct 24 14:03:41 IRST 2017 Script switched from XYZ to ZEN
Tue Oct 24 15:43:16 IRST 2017 Script switched from ZEN to XYZ
Tue Oct 24 17:07:25 IRST 2017 Script switched from XYZ to ZEN
Tue Oct 24 18:40:48 IRST 2017 Script switched from ZEN to XLS
Tue Oct 24 19:52:26 IRST 2017 Script switched from XLS to XYZ
Tue Oct 24 20:20:30 IRST 2017 Script switched from XYZ to ZEN
Tue Oct 24 20:36:06 IRST 2017 Script switched from ZEN to XLS
Tue Oct 24 21:01:03 IRST 2017 Script switched from XLS to XYZ
Tue Oct 24 21:47:47 IRST 2017 Script switched from XYZ to ZEN
How do I get total time spent on each script with bash
So the output shows like this:
abc 2 hours 30 min 40 sec
XYZ 3 hours 23 min 45 sec
zen ...
XLS ...
Assuming you have a log file named test.txt, following script should work,
#!/bin/bash
dtime=0
sname=""
while read line
do
_dtime=$(echo "$line" | awk '{print $1,$2,$3,$4}')
_sname=$(echo "$line" | awk '{print $10}')
_dtimesec=$(date +%s -d "$_dtime")
_timediff=$(( _dtimesec - dtime ))
[ "x$sname" != "x" ] && printf "$sname %d hours %d minutes %d seconds\n" $(($_timediff/3600)) $(($_timediff%3600/60)) $(($_timediff%60))
dtime=$_dtimesec
sname=$_sname
done < test.txt
This will produce an output like the following:
]$ ./test
abc 2 hours 5 minutes 47 seconds
XYZ 1 hours 39 minutes 35 seconds
ZEN 1 hours 24 minutes 9 seconds
XYZ 1 hours 33 minutes 23 seconds
ZEN 1 hours 11 minutes 38 seconds
XLS 0 hours 28 minutes 4 seconds
XYZ 0 hours 15 minutes 36 seconds
ZEN 0 hours 24 minutes 57 seconds
XLS 0 hours 46 minutes 44 seconds
EDIT
In order to find total amount of time spent by each script, this modified script should do the job:
#!/bin/bash
dtime=0
sname=""
namearr=()
timearr=()
while read line
do
_dtime=$(echo "$line" | awk '{print $1,$2,$3,$4}')
_sname=$(echo "$line" | awk '{print $10}')
_dtimesec=$(date +%s -d "$_dtime")
_timediff=$(( _dtimesec - dtime ))
_rc=1
for n in "${!namearr[#]}"
do
if [ "${namearr[$n]}" == "$_sname" ]; then
export _rc=$?
export ind=$n
break;
else
export _rc=1
fi
done
if [ $_rc -eq 0 ]; then
timearr[$ind]=$(( ${timearr[$ind]} + _timediff ))
else
if [ $dtime -eq 0 ] && [ "x$sname" == "x" ]; then
:
else
namearr+=($_sname)
timearr+=($_timediff)
fi
fi
dtime=$_dtimesec
sname=$_sname
done < test.txt
echo "Total time spent by each script:"
echo
for i in "${!namearr[#]}"
do
_gtime=${timearr[$i]}
printf "${namearr[$i]} %d hours %d minutes %d seconds\n" $(($_gtime/3600)) $(($_gtime%3600/60)) $(($_gtime%60))
done
Result:
$ ./test
Total time spent by each script:
XYZ 4 hours 44 minutes 44 seconds
ZEN 3 hours 28 minutes 34 seconds
XLS 1 hours 36 minutes 35 seconds
You can use the following gawk program:
time_spent.awk
BEGIN {
months["Jan"] = "01"
months["Feb"] = "02"
months["Mar"] = "03"
months["Apr"] = "04"
months["May"] = "05"
months["Jun"] = "06"
months["Jul"] = "07"
months["Aug"] = "08"
months["Seb"] = "09"
months["Oct"] = "10"
months["Nov"] = "11"
months["Dec"] = "12"
}
{
split($4, time, ":")
# mktime() manual: https://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html
now = mktime($6" "months[$2]" "$3" "time[1]" "time[2]" "time[3])
prv = $(NF-2)
cur = $(NF)
start[cur] = now
spent[prv]+=start[prv]?now-start[prv]:0
}
END {
for(i in spent) {
printf "%s seconds spent in %s\n", spent[i], i
}
}
Save it into a file time_spent.awk and execute it like this:
gawk -f time_spent.awk input.log
Output from the above example:
5795 seconds spent in XLS
0 seconds spent in abc
17084 seconds spent in XYZ
12514 seconds spent in ZEN
#!/usr/bin/env python
import sys
from time import strptime
from datetime import datetime
intervals = (
('weeks', 604800), # 60 * 60 * 24 * 7
('days', 86400), # 60 * 60 * 24
('hours', 3600), # 60 * 60
('minutes', 60),
('seconds', 1),
)
def display_time(seconds, granularity=2):
result = []
for name, count in intervals:
value = seconds // count
if value:
seconds -= value * count
if value == 1:
name = name.rstrip('s')
result.append("{} {}".format(value, name))
return ' '.join(result[:granularity])
with open(sys.argv[1], "rb") as df:
lines = df.readlines()
totals = {}
for i in range(len(lines)-1):
(_,t1,t2,t3,_,t4,_,_,_,_,_,scr) = lines[i].strip().split(' ')
st = datetime.strptime(' '.join([t1,t2,t3,t4]), "%b %d %H:%M:%S %Y")
(_,t1,t2,t3,_,t4,_,_,_,_,_,_) = lines[i+1].strip().split(' ')
et = datetime.strptime(' '.join([t1,t2,t3,t4]), "%b %d %H:%M:%S %Y")
if scr not in totals:
totals[scr] = 0
totals[scr] += (et-st).seconds
print("{} {}".format(scr,display_time((et-st).seconds, 3)))
print("\nTotals:")
for scr in totals:
print("{} {}".format(scr,display_time(totals[scr], 3)))
Here is the output, assuming your times are in a file named logfile:
$ ./times.py logfile
XYZ 2 hours 5 minutes 47 seconds
ZEN 1 hour 39 minutes 35 seconds
XYZ 1 hour 24 minutes 9 seconds
ZEN 1 hour 33 minutes 23 seconds
XLS 1 hour 11 minutes 38 seconds
XYZ 28 minutes 4 seconds
ZEN 15 minutes 36 seconds
XLS 24 minutes 57 seconds
XYZ 46 minutes 44 seconds
Totals:
XLS 1 hour 36 minutes 35 seconds
XYZ 4 hours 44 minutes 44 seconds
ZEN 3 hours 28 minutes 34 seconds
$
Note: I lifted the handy display_time function from here: Python function to convert seconds into minutes, hours, and days.
How to use cal command to add the calendar of next July to the end of the file, for example, myfile, and what day of the week the upcoming Canada Day fall on?
So far I just have this command:
cal July 2017 >> myfile
I feel like I am not doing it correct and I don't know which command to use, to find the day of the week for specific date.
Use this command:
cal 7 2017 >> file
The output is:
July 2017
Su Mo Tu We Th Fr Sa
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
You can find out day of week of a particular day with the GNU date command:
date -d"2017-07-01" # what day of week is Canada Day this year?
=> Sat Jul 1 00:00:00 UTC 2017
If you just want the week day, then:
date -d"2017-07-01" +%A
=> Saturday
You can check more about these commands with man cal or man date.
On a Mac, you could do this:
date -j -vJulm -v1d -v2017y +%A
See more on this post: date command on Mac OS
I am calculating how much time my code is taking in shell script -
date1=$(date +"%s")
# some code here
date2=$(date +"%s")
diff=$(($date2-$date1))
echo "Time Taken - $(($diff / 60)) minutes and $(($diff % 60)) seconds elapsed."
Above script prints out time taken in minutes and seconds. How can I add it for hours as well? Meaning it should print out Time Taken - 0 hours 54 minutes 0 seconds something like this.
Try this:
echo "Time Taken - $((diff /60/60)) hours and $(($diff % 60)) minutes and $(($diff % 60)) seconds elapsed."
if you're starting with integer seconds that all fall within a single day, and only need HH:MM:SS, here's a very strange way to use jot + bc :
jot -w 'obase = 60; ' - 91 86400 9091 | bc
01 31
02 33 02
05 04 33
07 36 04
10 07 35
12 39 06
15 10 37
17 42 08
20 13 39
22 45 10
I've got a date string as such:
Tue Jul 29 2014 23:44:06 GMT+0000 (UTC)
How can I add two hours to this?
So I get:
Tue Jul 29 2014 01:44:06 GMT+0000 (UTC)
Here's one solution:
var date = new Date('Tue Jul 29 2014 23:44:06 GMT+0000 (UTC)').getTime();
date += (2 * 60 * 60 * 1000);
console.log(new Date(date).toUTCString());
// displays: Wed, 30 Jul 2014 01:44:06 GMT
Obviously once you have the (new) date object, you can format the output to your liking if the native Date functions do not give you what you need.
Using MomentJS:
var moment = require('moment');
var date1 = moment("Tue Jul 29 2014 23:44:06 GMT+0000 (UTC)");
//sets an internal flag on the moment object.
date1.utc();
console.log(date1.format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ (UTC)"));
//adds 2 hours
date1.add(2, 'h');
console.log(date1.format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ (UTC)"));
Prints out the following:
Tue Jul 29 2014 23:44:06 GMT+0000 (UTC)
Wed Jul 30 2014 01:44:06 GMT+0000 (UTC)
This works well:
const epoch = new Date('01-01-2000')
const notBeforeDate = new Date(epoch).setSeconds(notBefore)
const notAfterDate = new Date(epoch).setSeconds(notAfter)
NOTE: the setSeconds() call actually adds seconds to the current Date value, it does not reset the Date to some absolute number of seconds. This detail is poorly addressed in the documentation and causes a lot of heartache when first trying to work with Dates in JavaScript.