Shell: days and dates

Code shell


#!/bin/bash
# given month, day and weekday, get the most recent year that match it

usage() {
    echo "$(basename $0) weekday month day"
    echo "(example: $(basename $0) wed aug 3 )"
    exit 1
}

# check for arguments
if [ $# -ne 3 ]; then
    usage
fi
weekday=$1
month=$2
day=$3

# parse arguments, translate them to lowcase, truncate them to 3 chars
weekday=$(echo $weekday | tr '[:upper:]' '[:lower:]' | cut -c1-3)
month=$(echo $month | tr '[:upper:]' '[:lower:]' | cut -c1-3)

# get the current date
eval $(date "+thismonth=%m; thisday=%d; thisyear=%Y")

# get month number and weekday number
monthnum=$(echo $month | sed -e \
    's/jan/1/;s/feb/2/;s/mar/3/;s/apr/4/;s/may/5/;s/jun/6/;s/jul/7/;s/aug/8/;s/sep/9/;s/oct/10/;s/nov/11/;s/dec/12/')
weekdaynum=$(echo $weekday | sed -e \
    's/mon/1/;s/tue/2/;s/wed/3/;s/thu/4/;s/fri/5/;s/sat/6/;s/sun/7/;')
monthname=$(echo $month | sed -e \
    's/10/oct/;s/11/nov/;s/12/dec/;s/1/jan/;s/2/feb/;s/3/mar/;s/4/apr/;s/5/may/;s/6/jun/;s/7/jul/;s/8/aug/;s/9/sep/')
# get the most recent year to start with
if [ $monthnum -gt $thismonth ]; then
    mostrecent=$(($thisyear - 1))
elif [ $monthnum -eq $thismonth -a $day -gt $thisday ]; then
    mostrecent=$(($thisyear - 1))
else
    mostrecent=$thisyear
fi

echo $monthname $day $mostrecent
# iterate over the years, looking for a match
weekdaynum_of_that_year=$(date -d "$monthname $day $mostrecent" +%u)
while [ $weekdaynum_of_that_year -ne $weekdaynum ]; do
    mostrecent=$(($mostrecent-1))
    weekdaynum_of_that_year=$(date -d "$monthname $day $mostrecent" +%u)
done

# output result
echo "Most recent year for weekday=$weekday, month=$month, day=$day is $mostrecent"


Code bash

(another way to implement it -- parse the output result of cal with sed, tr and cut) this


#!/bin/bash
# given month, day and weekday, get the most recent year that match it
# set -x
usage() {
    echo "$(basename $0) weekday month day"
    echo "(example: $(basename $0) wed aug 3 )"
    exit 1
}

# check for arguments
if [ $# -ne 3 ]; then
    usage
fi
weekday=$1
month=$2
day=$3

# parse arguments, translate them to lowcase, truncate them to 3 chars
weekday=$(echo $weekday | tr '[:upper:]' '[:lower:]' | cut -c1-3)
month=$(echo $month | tr '[:upper:]' '[:lower:]' | cut -c1-3)

# get the current date
eval $(date "+thismonth=%m; thisday=%d; thisyear=%Y")

# get month number and weekday number
monthnum=$(echo $month | sed -e \
    's/jan/1/;s/feb/2/;s/mar/3/;s/apr/4/;s/may/5/;s/jun/6/;s/jul/7/;s/aug/8/;s/sep/9/;s/oct/10/;s/nov/11/;s/dec/12/')
weekdaynum=$(echo $weekday | sed -e \
    's/mon/1/;s/tue/2/;s/wed/3/;s/thu/4/;s/fri/5/;s/sat/6/;s/sun/7/;')
monthname=$(echo $month | sed -e \
    's/10/oct/;s/11/nov/;s/12/dec/;s/1/jan/;s/2/feb/;s/3/mar/;s/4/apr/;s/5/may/;s/6/jun/;s/7/jul/;s/8/aug/;s/9/sep/')
# get the most recent year to start with
if [ $monthnum -gt $thismonth ]; then
    mostrecent=$(($thisyear - 1))
elif [ $monthnum -eq $thismonth -a $day -gt $thisday ]; then
    mostrecent=$(($thisyear - 1))
else
    mostrecent=$thisyear
fi

# parse the output of cal and get the answer
while true; do
    cmd="cal -h ${monthnum} ${mostrecent} | grep \"\b${day}\b\" | sed 's/[ ][ ][ ]\|[ ][ ]\|[ ]/|/g; s/^|//; s/|/\n/g' | cat -n | grep \"\b${day}\b$\" | tr -s [:space:] ' '| cut -d' ' -f2"
    weekdaynum_of_that_year=$(eval $cmd)
    weekdaynum_of_that_year=$(($weekdaynum_of_that_year - 1))
    [ $weekdaynum_of_that_year -eq 0 ] && weekdaynum_of_that_year=7
    if [ $weekdaynum_of_that_year -eq $weekdaynum ]; then break; fi
    let mostrecent=$mostrecent-1
    # echo -n "Debug: press [enter] to continue ..."
    #  read ign
done

# output result
echo "Most recent year for weekday=$weekday, month=$month, day=$day is $mostrecent"

-h option for cal is necessary for dealing with 'today' correctly spa

Code code

相關文章
相關標籤/搜索