## Tuesday, March 27, 2012

### What Week Day Is That Date in the Past?

A solution for: http://www.linuxjournal.com/content/work-shell-what-day-date-past

No AWK involved.

#!/bin/bash

# We need 3 arguments:
# DOW, Month and Day

if [ \$# -ne 3 ]
then
echo "Usage: \$(basename \$0) weekday month day"
echo "(example: \$(basename \$0) 4 3 2)"
exit 1
fi

# We use the date command for checking

date -d "\$2/\$3" &> /dev/null

if [ "\$?" == "1" ]
then
echo "\$(basename \$0) Error: Invalid date!"
exit 1
fi

# Month as number
M=\$(date -d "\$2/\$3" +%m)

# The day of the month
D=\$(date -d "\$2/\$3" +%e | sed 's/ //')

WD=\$1

# The day of year is gonna help us decide which is
# the first year to test: current year or the previous one
DOY=\$(date -d "\$2/\$3" +%j)
CDOY=\$(date +%j)

Y=\$(date +%Y)

if [ \${DOY} -gt \${CDOY} ]
then
Y=\$(expr \${Y} - 1)
fi

echo \$M \$D \$WD \$DOY \$CDOY \$Y

F=''
until [ -n "\${F}" ]
do
echo -n \$Y \$M =

# The calendar for the month and year
# Extract the line with the day of the month
# Add numbers to the lines, the number will be
# used to identify the Day of the Week
# Extract the line of the particular day
# gotta be careful cause 6 1 is the sixth line day 1
# and 1 6 is the first line day 6, so we search by the second number
# Convert the multiple spaces in front of the numbers into one space
# so the cut command always return the second field
# Extract the first number only, that's the DOW

CWD=\$(cal \${M} \${Y} \

| grep "\b\${D}\b" \
| sed 's/[ ][ ][ ]\|[ ][ ]\|[ ]/|/g; s/^|//; s/|/\n/g' \
| cat -n \
| grep "\b\${D}\b\$" \
| tr -s [:space:] ' ' \
| cut -d ' ' -f 2)

if [ \${WD} -eq \${CWD} ]
then
F=Found
fi

echo \$CWD

Y=\$(expr \${Y} - 1)
done

##END##

The output of searching the first date in the past when March 1 was Wednesday:

janeiros@harlie:~/tmp\$ ./t.sh 4 3 1
03 1 4 061 087 2012
2012 03 =5
2011 03 =3
2010 03 =2
2009 03 =1
2008 03 =7
2007 03 =5
2006 03 =4

janeiros@harlie:~/tmp\$ cal 3 2006
March 2006
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