正常化日期格式


正常化日期格式
 
01
normdata.sh
02
 #!/bin/sh
03
  
04
 # normdata.sh -- 在日期中将月份正常化为3个字母,第一个字母大写。
05
 # 对于第7个脚本valid-date很有帮助的函数。
06
  
07
 monthnoToName()
08
 {
09
     # 把变量'month'设置为一个适当的值
10
     case $1 in
11
         1 ) month="Jan";;  2 ) month="Feb";;
12
         3 ) month="Mar";;  4 ) month="Apr";;
13
         5 ) month="May";;  6 ) month="Jun";;
14
         7 ) month="Jul";;  8 ) month="Aug";;
15
         9 ) month="Sep";;  10) month="Oct";;
16
         11) month="Nov";;  12) month="Dec";;
17
         * )echo "$0: Unknown numeric month value $1" >&2; exit 1
18
     esac
19
     return 0
20
 }
21
  
22
 ### 脚本的主要部分
23
  
24
 if [ $# -ne 3 ]; then
25
     echo "Usage: $0 month day year" >&2
26
     echo "Typical input formats are August 3 1962 and 8 3 2002" >&2
27
     exit 1
28
 fi
29
  
30
 if [ $3 -lt 99 ] || [ $3 -gt 9999 ]; then
31
     echo "$0: expected four-digit year value." >&2; exit 1
32
 fi
33
  
34
 if [ -z $(echo $1 | sed 's/[[:digit:]]//g') ]; then
35
     monthnoToName $1
36
 else
37
     # 正常化开头的3个字母,第一个大写,剩下的小写
38
     month="$(echo $1 | cut -c1 | tr '[:lower:]' '[:upper:]')"
39
     month="$month$(echo $1 | cut -c2-3 | tr '[:upper:]' '[:lower:]')"
40
 fi
41
  
42
 echo $month $2 $3
43
  
44
 exit 0
脚本如何工作
   注意第3个条件语句:
 
if [ -z $(echo $1 | sed 's/[[:digit:]]//g') ]; then
   它去掉了所有的数字,然后使用-z来测试看看结果是不是为空。如果结果为空,第一个输入域肯定是一个或多个数字,所以调用函数monthnoToName后将它映射到了一个月份的名字上。如果不为空,通过2个子shell转义序列(即由$符号和左右圆括号括起来的序列,这样的目的是调用封装的命令,然后将输出替换掉),一个由cut和tr组成的管道就会用来生成月份。第一个序列仅仅是提取了第一个字符,然后用tr命令将它大写化。(注:序列echo $1 | cut -c1也
可以写成${1%${1#?}}。)第二个序列提取了第2和第3个字符,然后将它们小写化。
 
   运行脚本:
   为了确保对将来包含了normdata功能的脚本最大的适应性,这个脚本被设计成可以在命令行接受3个域的输入。如果你仅仅是想要交互式的使用这个脚本,相比之下,你要提示用户是3个域,不过这样的话,要是想从别的脚本调用normdate的话就不大方便了。
 
   结果:
   这个脚本完成了我们所期望的:只要日期格式相对简单点,就可以将它正常化,(已知的月份名字,月份的值在1-12之间,还有一个4个数字的年份)。比如:
 
 结果
1 ./normdate.sh 8 3 62 2 ./normdate.sh: expected four-digit year value. 3 ./normdate.sh 8 3 1962 4 Aug 3 1962 5 ./normdate.sh AUGust 3 1962 6 Aug 3 1962
   延伸阅读:
   在你因为自己可以添加很多的扩展到这个脚本中而变得太兴奋之前,可以看看脚本7,它使用了normdate来正确话输入的日期。不管怎样,你现在就可以做的一个改动是,马上增加下面的一小段代码到脚本的开头测试部分,你的脚本就可以接受形式为MM/DD/YYYY或MM-DD-YYYY格式的日期了:
 
1 if [ $# -eq 1 ]; then 2 set -- $(echo $1 | sed 's/[\/\-]/ /g') 3 fi
测试下:
 
1 ./normdate.sh March-11-1911 2 Mar 11 1911 3 ./normdate.sh 8/3/1962 4 Aug 3 1962
最后的脚本是:
 
 
01
完整的normdate.sh
02
 #!/bin/sh
03
  
04
 monthToName()
05
 {
06
     case $1 in
07
         1 ) month="Jan";;  2 ) month="Feb";;
08
         3 ) month="Mar";;  4 ) month="Apr";;
09
         5 ) month="May";;  6 ) month="Jun";;
10
         7 ) month="Jul";;  8 ) month="Aug";;
11
         9 ) month="Sep";;  10) month="Oct";;
12
         11) month="Nov";;  12) month="Dec";;
13
         * )echo "$0: Unknown numeric month value $1" >&2; exit 1
14
     esac
15
     return 0
16
 }
17
  
18
 if [ $# -eq 1 ]; then
19
     set -- $(echo $1 | sed 's/[\/\-]/ /g')
20
 fi
21
  
22
 if [ $# -ne 3 ]; then
23
     echo "Usage: $0 month day year" >&2
24
     echo "Typical input formats are August 3 1962 and 8 3 2002" >&2
25
     exit 1
26
 fi
27
  
28
 if [ $3 -lt 99 ] || [ $3 -gt 9999 ]; then
29
     echo "$0: expected four-digit year value." >&2; exit 1
30
 fi
31
  
32
 if [ -z $(echo $1 | sed 's/[[:digit:]]//g') ]; then
33
     monthToName $1
34
 else
35
     month="$(echo $1 | cut -c1 | tr '[:lower:]' '[:upper:]')"
36
     month="$month$(echo $1 | cut -c2-3 | tr '[:upper:]' '[:lower:]')"
37
 fi
38
  
39
 echo $month $2 $3
40
  
41
 exit 0
 

相关内容

    暂无相关文章