当前位置: 首页 > news >正文

第一章:The Missing Code Library--3.正常化日期格式

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

   Shell脚本开发过程中的一个不确定的问题就是前后不一致的数据格式的数目。要正常化他们,可能很难也可能比较简单。日期格式就是最有挑战性的一种,因为一个日期可以有多种特定方式的写法。即使你提出了一个特定的格式,比如“月份 几号 年份”,也有可能得到一个不符合条件的输入:月份是用的数字,而不是名称,或是月份的名称用的是一个缩写(英文中比如11月是Nov.),再或是一个全是大写的完整月份名。由于这个原因,一个正常化日期的函数,虽然自身还只是有点初级功能,但是以后会证实在一个更完备的脚本中会是多么的有用处,特别是第7个脚本--正确化日期格式。

normdata.sh
 #!/bin/sh
 
 # normdata.sh -- 在日期中将月份正常化为3个字母,第一个字母大写。
 # 对于第7个脚本valid-date很有帮助的函数。
 
 monthnoToName()
 {
     # 把变量'month'设置为一个适当的值
     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 ] || [ $3 -gt 9999 ]; then
     echo "$0: expected four-digit year value." >&2; exit 1
 fi
 
 if [ -z $(echo $1 | sed 's/[[:digit:]]//g') ]; then
     monthnoToName $1
 else
     # 正常化开头的3个字母,第一个大写,剩下的小写
     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

脚本如何工作
   注意第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

最后的脚本是:

完整的normdate.sh
 #!/bin/sh
 
 monthToName()
 {
     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 [ $# -eq 1 ]; then
     set -- $(echo $1 | sed 's/[\/\-]/ /g')
 fi
 
 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 ] || [ $3 -gt 9999 ]; then
     echo "$0: expected four-digit year value." >&2; exit 1
 fi
 
 if [ -z $(echo $1 | sed 's/[[:digit:]]//g') ]; then
     monthToName $1
 else
     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


转载于:https://my.oschina.net/u/578519/blog/100776

相关文章:

  • [Step By Step]在SAP Business Objects Data Services中使用SQL Transform将数据导入到SAP HANA中(SQL Transform)...
  • RTOS姊妹花——Small RTOS与STOS++简介
  • 微服务架构适用场景分析
  • 尚科推广专家当于同行的一款独立软式解决方案
  • 《Typecript 入门教程》 3、接口
  • 《把时间当朋友》 读书笔记
  • 在开发中你可能没有考虑到的两个性能优化
  • Kali***(二)之被动信息收集——搜索引擎
  • 编码格式导致批处理文件bat文件不能执行
  • 我的信仰
  • 陶哲轩实分析公理8.1——选择公理
  • C# 小测试(一):类成员初始化与构造函数执行的顺序
  • debian中安装和编译ipvsadm问题
  • kubernetes 1.8 高可用安装(三)
  • Putty中为CentOS 5.5配置SSH证书登录验证(转)
  • 深入了解以太坊
  • [PHP内核探索]PHP中的哈希表
  • python3.6+scrapy+mysql 爬虫实战
  • @angular/forms 源码解析之双向绑定
  • AngularJS指令开发(1)——参数详解
  • go append函数以及写入
  • JavaScript设计模式之工厂模式
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • Java知识点总结(JavaIO-打印流)
  • mysql常用命令汇总
  • 构造函数(constructor)与原型链(prototype)关系
  • 记录一下第一次使用npm
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 前端性能优化——回流与重绘
  • 我看到的前端
  • 项目管理碎碎念系列之一:干系人管理
  • 用jQuery怎么做到前后端分离
  • 云大使推广中的常见热门问题
  • 自制字幕遮挡器
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • 2017年360最后一道编程题
  • hi-nginx-1.3.4编译安装
  • ​卜东波研究员:高观点下的少儿计算思维
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (七)c52学习之旅-中断
  • (三十五)大数据实战——Superset可视化平台搭建
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (转)iOS字体
  • .[hudsonL@cock.li].mkp勒索加密数据库完美恢复---惜分飞
  • .gitignore文件_Git:.gitignore
  • .Net FrameWork总结
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .NET 中 GetProcess 相关方法的性能
  • .Net(C#)常用转换byte转uint32、byte转float等
  • .Net环境下的缓存技术介绍
  • @TableLogic注解说明,以及对增删改查的影响
  • @Transaction注解失效的几种场景(附有示例代码)