Issue
I have a todo list in todo.txt format.
I'd like to find the starting time ('t:2023-05-18') for all tasks with a date older than 10 days and remove the field from each matching line.
Sample Input Data
(A) Important task +project @context t:2023-05-07 due:2023-6-01 rec:1d
(B) Paint bedroom wall +house @bedroom t:2023-05-07 due:2023-6-07 rec:1d
(C) Pick up dry cleaning due:2023-05-19 +home @town
(C) Buy kitchen towels t:2023-05-19 +house @town
Expected Output Data
(A) Important task +project @context due:2023-6-01 rec:1d
(B) Paint bedroom wall +house @bedroom due:2023-6-07 rec:1d
(C) Pick up dry cleaning due:2023-05-19 +home @town
(C) Buy kitchen towels t:2023-05-19 +house @town
I'd like to remove the t:2023-05-07
field but only if the date is more than 10 days from today ('2023-05-18').
What I've Tried
I can set the date to 10 days ago using tenDaysAgo=$(date -d "-10 days" +%Y-%m-%d)
and then pass it through to Ed Morton's script which checks if the date in the ('t:
') field on each input line is in the past or not:
start-past.awk:
{
orig = $0
sched = ""
for (i=NF; i>0; i--)
{
if ( sub(/^t:/,"",$i) )
{
sched = $i
}
}
sched = substr(sched,1,10)
$0 = orig
}
sched < date
I can then manipulate the output with a sed
command to remove each t:<date>
field older than 10 days ago but I can only affect the output with this method and I need to update the actual data file.
I used the following:
$TODO_SH ls | awk '$0 ~ /t:/' \
| awk -v date="$tenDaysAgo" -f ~/bin/todo/start-past.awk \
|sed -E 's/t:[0-9]{4}-[0-9]{2}-[0-9]{2}//g' | sort -k2
My Results
I have managed to remove the 't:
' field only from the output of viewing the todo.txt lines and I need to make these changes permanent in the datafile while only updating the relevant lines.
I presume I need some sort of gawk loop
within the start-past.awk
script that I'm using but this is where my awk
abilities stop short.
Solution
Assumptions:
t:
entries always contain a date of the formatYYYY-MM-DD
(ie, month and day are always 2 digits); otherwise we'll need to add some code to insure the month and day are expanded to 2 digits so that the string comparison (sched < date
) works- a line can contain zero or one
t:
entry (ie, a line will not have two, or more,t:
entries)
To simulate the output from OP's $TODO_SH ls
call:
$ cat todo.dat
(A) Important task +project @context t:2023-05-07 due:2023-6-01 rec:1d
(B) Paint bedroom wall +house @bedroom t:2023-05-07 due:2023-6-07 rec:1d
(C) Pick up dry cleaning due:2023-05-19 +home @town
(C) Buy kitchen towels t:2023-05-19 +house @town
One awk
idea that replaces OP's current awk | awk | sed
tuple:
$ cat todo.awk
{ if ( match($0,/t:[0-9]{4}-[0-9]{2}-[0-9]{2}/) ) {
sched = substr($0,RSTART+2,10)
if ( sched < date )
$0 = substr($0,1,RSTART-1) substr($0,RSTART+RLENGTH+1)
}
}
1
Taking for a test drive:
$ cat todo.dat | awk -v date="$tenDaysAgo" -f todo.awk
(A) Important task +project @context due:2023-6-01 rec:1d
(B) Paint bedroom wall +house @bedroom due:2023-6-07 rec:1d
(C) Pick up dry cleaning due:2023-05-19 +home @town
(C) Buy kitchen towels t:2023-05-19 +house @town
NOTES:
- see GNU awk : String Functions for a description of the
match()
andsubstr()
functions - not sure the purpose of OP's
sort -k2
so I'll leave it up to OP to decide if this needs to be applied - OP mentions the need to make permanent changes to
the datafile
but we're not provided with any files (just the output from the$TODO_SH ls
call); if OP has problems updatingthe datafile
then I'd suggest asking a new question that focuses specifically on the datafile
Answered By - markp-fuso Answer Checked By - David Goodson (WPSolving Volunteer)