记录日程安排脚本


记录日程安排脚本
 
  这个脚本事实上是2个脚本,用来执行一个简单的日历程序。第一个脚本,addagenda.sh,它可以存储两种事件:可重复发生的、一次性发生的。它允许用户指定天数、周或是年。所有的日期都被合法化后保存了起来,同时在家目录下的.agenda文件中还有一行关于事件的描述信息。第二个脚本中,agenda.sh中核实所有的事件,会显示所有安排对应日期的日程。 
我觉得这个脚本非常有用,特别是在记录生日和周年纪念的时候。它真的给我减少了很多麻烦。 
 
代码:
 
addagenda.sh
 
01
#!/bin/sh
02
 
03
# addagenda.sh --提醒用户向事件脚本中添加新内容
04
 
05
agendafile="$HOME/.agenda"
06
 
07
isDayName()
08
{
09
    # 返回值 0,成功;1,失败
10
 
11
    case $(echo $1 | tr '[[:upper:]]' '[[:lower:]]') in
12
        sun*|mon*|tue*|wed*|thu*|fri*|sat*) retval=0;;
13
        *) retval=1;;
14
    esac
15
    return $retval
16
}
17
 
18
isMonthName()
19
{
20
    case $(echo $1 | tr '[[:upper:]]' '[[:lower:]]') in
21
        jan*|feb*|mar*|apr*|may*|jun*) return 0;;
22
        jul*|aug*|sep*|oct*|nov*|dec*) return 0;;
23
        *) return 1
24
    esac
25
}
26
 
27
normalize()
28
{
29
    # 返回的字符串中首字母大写,后续2个小写
30
    echo -n $1 | cut -c1 | tr '[[:lower:]]' '[[:upper:]]'
31
    echo $1 | cut -c2-3 | tr '[[:upper:]]' '[[:lower:]]'
32
}
33
 
34
if [ ! -w $HOME ]; then
35
    echo "$0: cannot write in your home directory($HOME)" >&2
36
    exit 1
37
fi
38
 
39
echo "Agenda: The Unix Reminder Service"
40
echo -n "Date of event(day mon, day month year, or dayname): "
41
read word1 word2 word3 junk
42
 
43
if isDayName $word1; then
44
    if [ ! -z "$word2" ]; then
45
        echo "Bad dayname format: just specify the day name by itself." >&2
46
        exit 1
47
    fi
48
    date="$(normalize $word1)"
49
else
50
    if [ -z "$word2" ]; then
51
        echo "Bad dayname format: unknown day name specified" >&2
52
        exit 1
53
    fi
54
 
55
    if [ ! -z "$(echo $word1 | sed 's/[[:digit:]]//g')" ]; then
56
        echo "Bad date format: please specify day first, by day number" >&2
57
        exit 1
58
    fi
59
 
60
    if [ "$word1" -lt 1 -o "$word1" -gt 31 ]; then
61
        echo "Bad date format: day number can only be in range 1-31" >&2
62
        exit 1
63
    fi
64
 
65
    if ! isMonthName $word2; then
66
        echo "Bad date format: unknown month name specified." >&2
67
        exit 1
68
    fi
69
 
70
    word2="$(normalize $word2)"
71
 
72
    if [ -z "$word3" ]; then
73
        date="$word1$word2"
74
    else
75
        if [ ! -z "$(echo $word3 | sed 's/[[:digit:]]//g')" ]; then
76
            echo "Bad date format: year value should be 2000-2500" >&2
77
            exit 1
78
        elif [ $word3 -lt 2000 -o $word3 -gt 2500 ]; then
79
            echo "Bad date format: year value should be 2000-2500" >&2
80
            exit 1
81
        fi
82
        date="$word1$word2$word3"
83
    fi
84
fi
85
 
86
echo -n "One-line description: "
87
read description
88
 
89
# Ready to write to data file
90
 
91
echo "$(echo $date | sed 's/ //g') | $description" >> $agendafile
92
 
93
exit 0
agenda.sh
01
#!/bin/sh
02
 
03
# agenda.sh --查看.agenda文件中是否有今明两天的安排
04
 
05
agendafile="$HOME/.agenda"
06
 
07
checkDate()
08
{
09
    # Create the possible default values that'll match today
10
    weekday=$1 day=$2 month=$3 year=$4
11
    format1="$weekday" format2="$day$month" format3="$day$month$year"
12
    # and step through the file comparing dates...
13
 
14
    IFS="|"    # the reads will naturally split at the IFS
15
 
16
    echo "On the Agenda for today:"
17
 
18
    while read data description; do
19
        if [ "$date" = "$format1" -o "$date" = "$format2" -o "$date" = "$format3" ]; then
20
            echo "$description"
21
        fi
22
    done < $agendafile
23
}
24
 
25
if [ ! -e $agendafile ]; then
26
    echo "$0: You don't seem to have an .agenda file." >&2
27
    echo "To remedy this, please use 'addagenda' to add events" >&2
28
    exit 1
29
fi
30
 
31
# Now let's get today's date...
32
 
33
eval $(date "+weekday=\"%a\" month=\"%b\" day=\"%e\" year=\"%G\"")
34
 
35
day="$(echo $day | sed 's/ //g')"    # remove possible leading space
36
 
37
checkDate $weekday $day $month $year
38
 
39
exit 0
addagenda.sh这个脚本,支持3中类型的事件:每周的(比如每个周三)、每年的(比如8月3号),以及一次性的(比如2010年1月10号)。而用户提供的日期会被程序压缩,比如用户给的日期是3 August,压缩后变为3Aug,或是Thursday变成了Thu。完成这个功能的代码是如下函数:
1
normalize()
2
{
3
    # 返回的字符串中首字母大写,后续2个小写
4
    echo -n $1 | cut -c1 | tr '[[:lower:]]' '[[:upper:]]'
5
    echo $1 | cut -c2-3 | tr '[[:upper:]]' '[[:lower:]]'
6
}
agenda.sh脚本通过日期来核实事件。并且该脚本会将这个日期转换为3中可能的日期格式(dayname, day+month, day+month+year)。它仅仅是简单的和.agenda文件中的行比较下。如果有匹配,就显示给用户。 
在我看来,最牛逼最狂霸酷炫拽的地方是如何应用一个eval表达式一次性的分配4个日期值给变量的: 
1
eval $(date "+weekday=\"%a\" month=\"%b\" day=\"%e\" year=\"%G\"")
同样,一个接一个提取值也是可以的(比如,weekday="$(date +%a)"),但在有些非常罕见的情况中,这种方法可能会失效:在4个日期请求的中间部分,此时真实日期滚动到了新的一天,因此一个简洁的单一调用更好(注:这个单一的句子就相当于一个原子调用。类似操作系统中的竟态条件)。 
 
 
运行脚本,测试一下: 
 
01
$ addagenda
02
Agenda: The Unix Reminder Service
03
 
04
Date of event (day mon, day month year, or dayname): 31 October
05
One line description: Halloween
06
$ addagenda
07
Agenda: The Unix Reminder Service
08
 
09
Date of event (day mon, day month year, or dayname): 30 March
10
One line description: Penultimate day of March
11
$ addagenda
12
Agenda: The Unix Reminder Service
13
 
14
Date of event (day mon, day month year, or dayname): Sunday
15
One line description: sleep late (hopefully)
16
$ addagenda
17
Agenda: The Unix Reminder Service
18
 
19
Date of event (day mon, day month year, or dayname): marc 30 03
20
Bad date format: please specify day first, by day number
21
 
22
$ addagenda
23
Agenda: The Unix Reminder Service
24
 
25
Date of event (day mon, day month year, or dayname): 30 march 2003
26
One line description: IM Marv to see about dinner
27
 
28
Now the agenda script offers a quick and handy reminder of what's happening today:
29
 
30
$ agenda
31
On the Agenda for today:
32
Penultimate day of March
33
sleep late (hopefully)
34
IM Marv to see about dinner
35
 
36
Notice that it matched entries formatted as day+month, day of week, and day+month+year. For completeness, here's 
37
the associated .agenda file, with a few additional entries:
38
 
39
$ cat ~/.agenda
40
14Feb|Valentine's Day
41
25Dec|Christmas
42
3Aug|Dave's Birthday
43
4Jul|Independence Day (USA)
44
31Oct|Halloween
45
30Mar|Penultimate day of March
46
Sun|sleep late (hopefully)
47
30Mar2003|IM Marv to see about dinner
  这两个脚本在记录日记方面仅仅是起到了一个抛砖引玉的作用。要想搞的更好点,可以在脚本中做一点关于日期的数学运算。另外,如果匹配的日期没有日程安排,可以更人性化的输出一句别的什么内容。

相关内容

    暂无相关文章