I have a scheduled.txt file like this:
# Scheduled tasks for todo.txt # Format: # # a dow, Mon,Tue,Wed,... # b moy, Jan,Feb,Mar,... # d dom, 01..31 # D m/d/y 12/30/12 # F Y-m-d 2012-12-30 # j doy 001..366 # V woy 01..53 # # %2 = Division by 2 is possible # %N2= Devision by 2 is not possible # # Empy lines are ignored #===Planned===# V=%2 a=Sun ~Clean bed sheets # Every odd day j=%N2 ~Check wait # Every 3 days j=%3 ~Get finance up to date # First of the month d=01 ~Urenlijsten
This file is parsed by this script:
#!/bin/bash # 2 modes: debug || commit if [[ "x$1" = "xdebug" ]]; then COMMIT=false say(){ echo $*; } elif [[ "x$1" = "xcommit" ]]; then COMMIT=true say(){ return; } else echo 'debug or commit?' exit 1 fi SCHEDFILE=$HOME/todo/repeatedtasks.txt TODOFILE=$HOME/todo/todo.txt TEMPTODOFILE=`mktemp` # We work in a temporary file. Copying back happens at the end. [ $COMMIT = 'true' ] && cp $TODOFILE $TEMPTODOFILE addtask(){ TASK=$* say "ADDING $TASK" # Add if commit is true: if [ $COMMIT = 'true' ] ; then # We don't add tasks multiple times. If it's already there, append ! if grep -q "^$TASK" $TEMPTODOFILE ; then # There already, append ! sed -i "/$TASK/ s/$/\!/" $TEMPTODOFILE else # Not there already echo $TASK >> $TEMPTODOFILE fi fi } # Process each line in todo.txt egrep "^[a-zA-Z]+" $SCHEDFILE | while read SCHED ; do say say "==== Parsing $SCHED ====" TASK=$(echo $SCHED | cut -d\~ -f2 ) # We can have multiple date parts. They must all be true before a task is added. DATEPARTS=$(echo $SCHED | cut -d\~ -f1 | sed 's/ *$//g') say "The dateparts are [$DATEPARTS]" ADDME=no for DATEPART in $DATEPARTS; do # Parse this part # The parts of the line DATESTR=$(echo $DATEPART | cut -d= -f1 ) DATEVAL=$(echo $DATEPART | cut -d= -f2 ) say "Part $DATESTR = $DATEVAL" # Find the current date value for DATESTR DATESTR_FORMATTED='' for str in $DATESTR; do DATESTR_FORMATTED+="$str"; done CURDATEVAL=$(date +%$DATESTR_FORMATTED) say ". STR [$DATESTR_FORMATTED] is now [$CURDATEVAL], we match on [$DATEVAL]. " # Process rules if [[ $( echo $DATEVAL | egrep -o "^%" ) = '%' ]]; then # check for division (eg every .. weeks/days/..) say ". Checking [$CURDATEVAL] for division" # Actual checking NUMBER=$(echo $DATEVAL | egrep -o "[0-9]+") if [[ ! $(echo $DATEVAL | egrep -q "^%N" ) ]] ; then if [[ $(( $CURDATEVAL % $NUMBER )) -eq 0 ]]; then ADDME=yes ; else ADDME=no; break; fi else if [[ ! $(( $CURDATEVAL % $NUMBER )) -eq 0 ]]; then ADDME=yes ; else ADDME=no; break; fi fi else # Exact value say ". Checking for exact" if [[ x$CURDATEVAL = x$DATEVAL ]] ; then ADDME=yes ; else ADDME=no; break; fi fi say "Passed tests. Addme is still $ADDME" done say "Exiting loop dateparts. ADDME=$ADDME" # All parts are parsed if [[ "x$ADDME" = "xyes" ]] ; then addtask $TASK fi done [ $COMMIT = 'true' ] && sort $TEMPTODOFILE > $TODOFILE [ $COMMIT = 'true' ] && rm $TEMPTODOFILE
Questions are welcome at the ‘mail’ account on this domain.