Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15933116
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类:

2008-03-21 16:49:55

对于脚本的开发者来说,数据的资料格式不一致是一个很大的问题,要让它们能够标准化也是一个相当 棘手的问题。日期的格式是众多问题中的一个,因为日期的表示方式有许多种,即使我们使用"月日年"的方式来表示,我们也可能有不同的输入方式:月份的部份 我们可以输入英文的月份缩写或大写的全名。

基于这个理由,我特別编写一个基本的程序,这个程序对于你以后的脚本编写会有相当大的帮助。

脚本源代码

#!/bin/sh
# normdate -- Normalizes month field in date specification
# to three letters, first letter capitalized. A helper
# function for Script #7, valid-date. Exits w/ zero if no error.

monthnoToName()
{
  # Sets the variable 'month' to the appropriate value
  case $1 in
    1 ) month="Jan"    ;;  2 ) month="Feb"    ;;
    3 ) month="Mar"    ;;  4 ) month="Apr"    ;;
    5 ) month="May"    ;;  6 ) month="Jun"    ;;
    7 ) month="Jul"    ;;  8 ) month="Aug"    ;;
    9 ) month="Sep"    ;;  10) month="Oct"    ;;
    11) month="Nov"    ;;  12) month="Dec"    ;;
    * ) echo "$0: Unknown numeric month value $1" >&2; exit 1
   esac
   return 0
}

## 主程序

if [ $# -ne 3 ] ; then
  echo "Usage: $0 month day year" >&2
  echo "Typical input formats are August 3 1962 and 8 3 2002" >&2
  exit 1
fi

if [ $3 -lt 99 ] ; then
  echo "$0: expected four-digit year value." >&2; exit 1
fi

if [ -z $(echo $1|sed 's/[[:digit:]]//g') ]; then
  monthnoToName $1
else
  # Normalize to first three letters, first upper, rest lowercase
  month="$(echo $1|cut -c1|tr '[:lower:]' '[:upper:]')"
  month="$month$(echo $1|cut -c2-3 | tr '[:upper:]' '[:lower:]')"
fi

echo $month $2 $3

exit 0

工作原理

注意第三个判断式:
if [ -z $(echo $1|sed 's/[[:digit:]]//g') ]; then

它会将所有的数字刪除,并且利用 -z 来进行测试结果是不是空白字元,如果是空白字元,表示第一个字必定是数字,那么程序会调用monthnoToName来做查表的动作。接下来的两行会利用 cut与tr将月份的字母进行分离及转换。第一行是分离出第一个字元,再利用tr命令将它转换成大写字母(之前提过,以POSIX而言 echo $1|cut -c1 这种写法也可以写成 ${1%${1#?}} )。第二行是将第二及第三个字母转换成小写字母:

month="$(echo $1|cut -c1|tr '[:lower:]' '[:upper:]')"
month="$month$(echo $1|cut -c2-3 | tr '[:upper:]' '[:lower:]')"

运行脚本

为了让该脚本normdate在以后能有更大的应用空间,我们把脚本设计成可以在命令列上输入三个栏位的程序。另外,如果你想让此程序更具互动性,你应该要提示使用者输入三个栏位。相之下,两者之间似乎是后者较难。

结果

对于这个程序,我们希望它能夠将一个简单的日期(已知的月份名称或月份数字及四位数的年份)变成一个标准的日期格式。举例:

$ normdate 8 3 62
normdate: expected four-digit year value.
$ normdate 8 3 1962
Aug 3 1962
$ normdate AUGUST 3 1962
Aug 3 1962

改进与加强

这个脚本有很大的扩充性。另一方面,只要做一点点的修改,我们就可以让这个脚本接受不同的日期格式,例如MM/DD/YYYY或者是MM-DD-YYYY,请将底下的程序代码附加在刚才我们提及的判断式前:

if [ $# -eq 1 ] ; then # try to compensate for / or - formats
  set -- $(echo $1 | sed 's/[\/\-]/ /g')
fi

修改后,我们也可以输入这样的时间格式:

$ normdate March-11-1911
Mar 11 1911
$ normdate 8/3/1962
Aug 3 1962

阅读(946) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~