taskwarrior - Is it possible to report on the time spent on tasks? - taskwarrior

I'm trying to use taskwarrior to track time for billing purposes.
To do that I'm trying to generate a report showing the hours spend on each task. The standard completed report gives the Created and Completed dates but not times, so I cant see how many hours were spent on the task.
$ task completed project:test
ID UUID Created Completed Age Project Description
- fed3daca 2019-09-29 2019-09-29 10min test test1
- 31a8f13e 2019-09-29 2019-09-29 1min test test2
2 tasks
Is this something taskwarrior can do?
Thanks

I don't think taskwarrior can create those reports by itself, but you could use timewarrior to do that.
After you set up timewarrior, the time spent on each task will be tracked.
Example:
➜ ~ task add reply on stack overflow
Created task 341.
➜ ~ task start 341
Starting task 81b73133 'reply on stack overflow'.
Started 1 task.
Tracking "reply on stack overflow"
Started 2020-04-10T12:07:58
Current 59
Total 0:00:01
➜ ~ task 341 done
Completed task 81b73133 'reply on stack overflow'.
Completed 1 task.
Recorded "reply on stack overflow"
Started 2020-04-10T12:07:58
Ended 09:12
Total 0:01:14
By default you will see how much time you spent on the task. In case you start and stop the task multiple times or want to see the time you spent on a project or on tasks with a certain tag, you can query timewarrior directly:
➜ ~ timew summary 'reply on stack overflow'
Wk Date Day Tags Start End Time Total
W15 2020-04-10 Fri reply on stack overflow 12:07:58 12:09:12 0:01:14 0:01:14
0:01:14
This shows you the time you spent today on that task. You can also specify a time interval in case you want to see the total time spent on the task/project/tag.
Example:
➜ ~ timew summary 2020-01-01 - tomorrow 'reply on stack overflow'
Wk Date Day Tags Start End Time Total
W15 2020-04-10 Fri reply on stack overflow 12:07:58 12:09:12 0:01:14 0:01:14
0:01:14
To see how much time you spent on project test you can just run:
timew summary 2018-01-01 - tomorrow test
This will also include the tasks named 'test' and tasks with the tag test.

As mentioned by Tom Dörr use timewarrior to summarize by tags.
This is the way I do:
Collect the tags by date range, modify the date range for your needs:
timew tags :week
Remove the headings from the output:
timew tags :week | tail -n+4
Use awk to separate the fiels by dash and print first field:
timew tags :week | tail -n+4 | awk 'BEGIN {FS="-"}; {print $1}'
This results in a list of tags for the selected date range, each in one line. Now you can use a script (for example summarize.sh) to loop through these tags to summarize:
#!/bin/bash
while read TAG; do
[ "${TAG}" = "" ] && continue
timew summary :week "${TAG}"
done < <(timew tags :week | tail -n+4 | awk 'BEGIN {FS="-"}; {print $1}')
This way you can handle tags containing whitespace also.
At least, run a loop in shell/bash to update permanently, for example every second:
while :; do clear; date; ./summarize.sh; sleep 1; done

Related

How to run a python script between a particular times every single day (on Linux)?

I am looking for a way to be able to run a python script at a particular times of day and then have it auto terminated at another time of day. Ideally, I would want this to not be done within the script itself.
For example: I would want the script to start at 08:00 and end at 10:00 then start again at 11:30 and then terminate at 15:00 and I would need this to happen every day automatically.
I have browsed through many suggestions online, and many of them suggested to use cron, however, as far as I can see, cron does not natively offer the functionality of automatically terminating an application.
Others have suggested using cron to start the application at a particular time and then use another cron instance to create a "terminate" file that the program will search for at every loop iteration and if the file is present then the python script will terminate via a sys.exit() function or something, however, this seems quite janky and more of a workaround than a real solution.
You may use Jobber. You will be able to start scripts whenever you want and for the time you want.
Warning : Jobber is not free. You can try it for free though.
Here is the link to Jobber's website.
You could write a script that creates a lockfile with cron (https://unix.stackexchange.com/questions/12815/what-are-pid-and-lock-files-for), and use the lockfile to know what the process ID is, then terminate the process with that id using cron as well
After you have determined that the process name is uniquely identifiable you could do something like this (that's indeed also using cron).
0 8 * * * /path/to/unique_name.py& ( echo "pkill unique_name.py" | at 10:00 )
30 11 * * * /path/to/unique_name.py& ( echo "pkill unique_name.py" | at 15:30 )
Edit 1:
And "name safe" versions (using kill).
0 8 * * * /path/to/unique_name.py& echo kill $! | at 10:00
30 11 * * * /path/to/unique_name.py& echo kill $! | at 15:30

How to create cron job that is executing every 3 months?

I am using Hangfire in ASP.NET Core for Cron (recurring) Jobs, and I need to create a job that runs every three months starting from a given start date.
So if the start date was 15-Nov-2019, it should run on 15-Nov-2019, 15-Feb-2020, 15-May-2020 and so on and so forth.
And I need it to run every 3 months forever.
So I tried the following cron expression for this: "0 0 15 11/3 ?" or "0 0 15 11/3 *"
But after testing it on this translating site, it tells me that it will run on the following dates:
2019-11-15
2020-11-15
2021-11-15
2022-11-15
2023-11-15
So, if that is true, then how to make it run every three months starting from 15-Nov-2019 as described above and keep running forever?
The month field in cron takes a number between 1 and 12; depending on the cron implementation used, you could use an explicit list for the month field:
0 0 15 2,5,8,11 *
or a range with a step:
0 0 15 2-12/3 *
crontab.guru seems to support a single value with a step as well, but the crontab man page doesn't mention this style, so it might or might not work:
0 0 15 2/3 *
If you want to be able to set this up more than three months before you want it to run for the first time, you have to manually check the date; in shell (using GNU date), you would do something like this:
0 0 15 2-12/3 * [ $(date +%%s) -gt $(date -d '2019-11-01' +%%s) ] && yourcommand
This compares the current date to November 1st, 2019; if it is greater than that, the command is run.
Simple solution is to use the following command:
0 0 15 */3 *
It is very straight forward.Here's the output for your satisfaction from crontab.guru website
output of cron job

Is there any way to read text file and use words inside it as input?

I'm dealing with one task where I have to read the text file and take every word present in it as input & the important thing is I should have to do it by using while or any other loop (Without making use of awk command)
I tried it with while loop it is reading the file but I'm not able to figure out the next steps.
Here are the details :
Content File (Source File )
[root#localhost ~]# cat content.txt
Rantndeep,old spice,100,20
D-mart,toothbrush,30,20
more,sack,300,10
Required Output
[root#localhost ~]# sh parser.sh
Today I went to Rantndeep Store bought old spice For Rs. 100 And paid 20 Rs.as a parking charges
Today I went to D-mart Store bought toothbrush For Rs. 30 And paid 20 Rs.as a parking charges
Today I went to more Store bought sack For Rs. 300 And paid 10 Rs.as a parking charges
My Script
[root#localhost ~]# cat p.sh
#/bin/bash
cat content.txt | while read a
do
echo $a
done
This is only printing the contents of a file as mentioned above I want to script it by using any loop so that I could get the output as
[root#localhost ~]# sh parser.sh
Today I went to Rantndeep Store bought old spice For Rs. 100 And paid 20 Rs.as a parking charges
Today I went to D-mart Store bought toothbrush For Rs. 30 And paid 20 Rs.as a parking charges
Today I went to more Store bought sack For Rs. 300 And paid 10 Rs.as a parking charges
You are nearly at it. Note that you can use read to set more than one variable. Try
IFS=, # Because you separate the items using comma instead of space
while read w1 w2 w3 w4
do
echo "first word: $w1 second word: $w2 last word: $w4"
done < content.txt
you will see that on each iteration, w1... w4 contain the 4 fields of the respective line in content.txt

Bash Script Efficient For Loop (Different Source File)

First of all i'm a beginner in bash scripting. I usually code in Java but this certain task requires me to create some bash scripts in Linux. FYI i've already made a working script but I think its not efficient enough because of the large files I'm dealing with.
The problem is simple I have 2 logs that I need to compare and make some correction on one of the logs... ill call it logA and logB. This 2 logs contains different format here is an example:
01/04/2015 06:48:59|9691427842139609|601113090635|PR|30.00|8.3|1.7| <- log A
17978712 2015-04-01 06:48:44 601113090635 SUCCESS DealerERecharge.<-log B
17978714 2015-04-01 06:48:49 601113090635 SUCCESS DealerERecharge.<-log B
As you can see there is a gap in time stamp. The actual logs that will match with log A is the one with the ID 17978714 because it is the closest time from it. The highest time gap I've seen is 1 minute. I cant use the RANGE logic because if there are more than one line on log B that is within the 1 minute range then all of the line will show in my regenerated log.
The script I made contains a for loop which iterate the timestamp of log A until it hits something in log B (The first one it hits is the closest)
Inside the for loop I have this line of code which makes the loop slow.
LINEOUTPUT=$(less $File2 | grep "Validation 1" | grep "Validation 2" | grep "Timestamp From Log A")
I've read some sample using SED but the problem is I have 2 more validation to consider before matching it with the time stamp.
The validation works as a filter to narrow down the exact match for log A and B.
Additional Info: I tried doing some benchmark test for the script I made by performing some loop. One thing I've noticed is that even though I only use 1 pipe for that script the loop tick is still slow.

How do I create a file that corresponds to the minute of the day?

suffix=$(date +%w)
touch ./$suffix.dat
That does it by the day of the week. How do I do it by the minute?
If you want the minute of the day (if I understood correctly you mean how many minutes are past since midnight), use this command:
$ echo "($(date +%k)*60)+$(date +%M)" | bc
503
date +%k is the number of hours past
date +%M the number of minutes
a calculation is formed like this: ( 8*60)+23
and pipe to bc that calcutales it
You run man date to get a full list of all the format codes. This will tell you quite clearly how to print the minute instead of the weekday.
In case your system doesn't have man pages installed, see here: http://unixhelp.ed.ac.uk/CGI/man-cgi?date
#!/bin/sh
hour=$(date +%H)
mins=$(date +%M)
mins_of_day=$(echo "60 * $hour + $mins"|bc)
touch $mins_of_day.dat

Resources