免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: quakelee
打印 上一主题 下一主题

还是日期计算!! [复制链接]

论坛徽章:
0
11 [报告]
发表于 2003-05-20 01:24 |只看该作者

还是日期计算!!

...

如果是要做得正规点,加上闰年的算法,不仅仅可以用在上个月的最后一天这种特殊情况,还可以处理一般情况:

  1. #!/bin/sh

  2. if [ $# -ne 0 ]; then
  3.     DateString=$1
  4.     Year=`echo $DateString | cut -b 1-4`
  5.     Month=`echo $DateString | cut -b 5-6`
  6.     Date=`echo $DateString | cut -b 7-8`
  7. else
  8.     Year=`date +%Y`
  9.     Month=`date +%m`
  10.     Date=`date +%d`
  11. fi

  12. Date=`expr $Date - 1`

  13. if [ $Date -eq 0 ]; then

  14.   Month=`expr $Month - 1`

  15.   if [ $Month -eq 0 ]; then
  16.     Year=`expr $Year - 1`
  17.     Month=12
  18.     Date=31

  19.   else
  20.     case $Month in
  21.       1|3|5|7|8|10|12) Date=31;;
  22.              4|6|9|11) Date=30;;
  23.                     2)
  24.         Date=28
  25.         if [  `expr $Year % 4` -eq 0 -a `expr $Year % 100` -ne 0  -o \
  26.               `expr $Year % 400` -eq 0  ]; then
  27.             Date=29
  28.         fi
  29.       ;;
  30.     esac
  31.   fi
  32. fi
复制代码


运行:(假设为 b.sh ,注意,参数比上面那个脚本多了两位,即日期)

sleeve@magic:~/test[594]$ ./b.sh 19960301
1996/2/29

sleeve@magic:~/test[595]$ ./b.sh 20000301
2000/2/29

sleeve@magic:~/test[596]$ ./b.sh 21000301
2100/2/28

sleeve@magic:~/test[597]$ ./b.sh 20030101
2002/12/31

sleeve@magic:~/test[598]$ ./b.sh
2003/05/18

sleeve@magic:~/test[599]$ ./b.sh 20030511
2003/05/10

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
12 [报告]
发表于 2003-05-20 08:40 |只看该作者

还是日期计算!!

红袖jj       
感动死了~~~
真是论坛第一大好人+PPMM
HOHO~

不过这个脚本运行起来还有的两个小问题嘿嘿
我就是跟你说一声,我今天有点事,其中一个来不及改了
其中一个问题不会改:(
我在SunOS5.8上run这个脚本的时候
如果输入是200x0301的话
就会出现
./getdate.sh: test: ] missing
我用的是第二个脚本
第二个小问题是,我需要返回的符合%Y%m%d的格式
所以会出现一个问题,需要在小于10的数字前面加个0嘿嘿
不过这个我会啦

论坛徽章:
0
13 [报告]
发表于 2003-05-20 09:58 |只看该作者

还是日期计算!!

红袖MM真是天下第一大好人+PPMM
又学到好东西了


唉,我什么时候能到红袖MM的水平啊
能有一半也行啊。

论坛徽章:
0
14 [报告]
发表于 2003-05-20 10:10 |只看该作者

还是日期计算!!

红袖老大终于回来了!

俺又长学问了!

论坛徽章:
0
15 [报告]
发表于 2003-05-20 22:43 |只看该作者

还是日期计算!!

...

大家过奖了。

To quakelee:

是啊,具体应用过程中是要调试一下的,上面的给出的代码只是个骨架,实际中是应该把可能遇到的情况考虑进去。在这里我给出一些情况,如参数中是否有非法字符、字串太长、太短、含有空格、日期超出范围……等等,但也不可能考虑周全,只能是具体情况具体分析,根据自己的要求来完善。

另外,上面的帖子中漏掉了最后一句打印语句,我今天才看到。居然你也没提起!

修改后代码,供参考:

  1. #!/bin/sh

  2. # since we have to validate the date string more than once
  3. # put the leap year algorithm in subroutine, should be easy
  4. # to be invoked.

  5. leap() {
  6.     case $1 in
  7.             1|3|5|7|8|10|12) Max=31;;
  8.                    4|6|9|11) Max=30;;
  9.                           2) if [ `expr $Year % 4` -eq 0 -a `expr $Year % 100` -ne 0 -o \
  10.                                   `expr $Year % 400` -eq 0 ]; then
  11.                                  Max=29
  12.                              else
  13.                                  Max=28
  14.                              fi
  15.                              ;;
  16.                           *) Max=0
  17.     esac
  18.     echo $Max
  19. }


  20. if [ $# -eq 1 ]; then
  21.     DateString=$1

  22.     # Len=${#DateString}         ## ksh or bash user can use this statement
  23.                                  ## otherwise use the following expression
  24.     Len=`expr "$DateString" : '.*'`

  25.     if [ $Len -gt 8 ]; then
  26.        echo "Date string too long!"
  27.        exit 1
  28.     elif [ $Len -lt 8 ]; then
  29.        echo "Date string too short!"
  30.        exit 1
  31.     fi

  32.     echo $DateString | grep '[^0-9]' > /dev/null 2>&1
  33.     if [ $? -eq 0 ]; then
  34.          echo "Invalid character(s) in date string! "
  35.          exit 1
  36.     fi

  37.     Year=`echo $DateString | cut -b 1-4`
  38.     Month=`echo $DateString | cut -b 5-6`
  39.     Month=`expr $Month - 0`     # remove leading zero
  40.     Date=`echo $DateString | cut -b 7-8`

  41.     DateMax=`leap $Month`

  42.     if [ $Month -gt 12 -o $Month -lt 1 -o $Date -gt $DateMax -o $Date -lt 1 ]; then
  43.          echo "Invalid date string format! either month or date range exceeds. "
  44.          exit 1
  45.     fi
  46.    
  47. else
  48.     Year=`date +%Y`
  49.     Month=`date +%m`
  50.     Date=`date +%d`
  51. fi

  52. Date=`expr $Date - 1`

  53. if [ $Date -eq 0 ]; then

  54.    Month=`expr $Month - 1`

  55.    if [ $Month -eq 0 ]; then
  56.       Year=`expr $Year - 1`
  57.       Month=12
  58.       Date=31

  59.    else
  60.       Date=`leap $Month`
  61.    fi
  62. fi

  63. if [ $# -ge 2 ]; then
  64.     echo "Only ONE argument required!
  65. Parameters will be discarded and use default current date"
  66. fi

  67. printf "%04d/%02d/%02d\n" $Year $Month $Date
复制代码

论坛徽章:
0
16 [报告]
发表于 2003-05-20 22:48 |只看该作者

还是日期计算!!

...

运行结果:

sleeve@magic:~/tmp/sh$ b.sh 2003
Date string too short!

sleeve@magic:~/tmp/sh$ b.sh 200312011
Date string too long!

sleeve@magic:~/tmp/sh$ b.sh 200x1201
Invalid character(s) in date string!

sleeve@magic:~/tmp/sh$ b.sh '200 1201'
Invalid character(s) in date string!

sleeve@magic:~/tmp/sh$ b.sh 200 1201
Only ONE argument required!
Parameters will be discarded and use default current date
2003/05/19

sleeve@magic:~/tmp/sh$ b.sh 20030301
2003/02/28

sleeve@magic:~/tmp/sh$ b.sh 20030101
2002/12/31

sleeve@magic:~/tmp/sh$ b.sh
2003/05/19

sleeve@magic:~/tmp/sh$ b.sh 20030707
2003/07/06

sleeve@magic:~/tmp/sh$ b.sh 20040301
2004/02/29

sleeve@magic:~/tmp/sh$ b.sh 20000301
2000/02/29

sleeve@magic:~/tmp/sh$ b.sh 19000301
1900/02/28

sleeve@magic:~/tmp/sh$ b.sh 19000335
Invalid date string format! either month or date range exceeds.

sleeve@magic:~/tmp/sh$ b.sh 20001503
Invalid date string format! either month or date range exceeds.

论坛徽章:
0
17 [报告]
发表于 2003-05-21 08:48 |只看该作者

还是日期计算!!

红袖真认真.

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
18 [报告]
发表于 2003-05-21 13:28 |只看该作者

还是日期计算!!

红袖jj呀,我其实看到了但是昨天改了一下我就懒得说了,这个脚本我运行好像还是有点问题:(
我也不知道怎么回事
这是在freebsd上运行的结果
[: missing ]
3: not found
2003/02/28
值倒是出来了,但是报了两个错误

论坛徽章:
0
19 [报告]
发表于 2003-05-21 17:50 |只看该作者

还是日期计算!!

...

原帖由 "nkliyong"] 红袖真认真.[/quote 发表:


蓝酷脚也是呀,

[quote]原帖由 "quakelee" 发表:
这是在freebsd上运行的结果
[: missing ]
3: not found
2003/02/28
值倒是出来了,但是报了两个错误


确实如此,原因是在第11行,因为太长了,分成两行写的,行末原本是个回车

2) if [ `expr $Year % 4` -eq 0 -a `expr $Year % 100` -ne 0 -o \[RETURN]
   `expr $Year % 400` -eq 0 ]; then

但是不知为啥,这个 phpBB 论坛中,从帖中 copy & paste 会在每行的末尾加上补上空格,变成了

2) if [ `expr $Year % 4` -eq 0 -a `expr $Year % 100` -ne 0 -o \[SPACE][RETURN]
   `expr $Year % 400` -eq 0 ]; then

在大多数情况下倒也是无伤大雅的,但是也有时候会出错,比如这里 \ 后面必须跟的是回车,经过转义的回车,表示该语句还没有结束,跟下一行是同一句。

以后,碰到这种情况我会尽量想着提醒一下的。

此外,还有加了空格会出现异常的还有:

... <<EOF
...

EOF

以及

sed '{
  ...
  w file
}
'

等情况。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
20 [报告]
发表于 2003-05-21 23:50 |只看该作者

还是日期计算!!

嘿嘿,我想了个更好的办法,把日志都同步到一台bsd上去处理了
嘿嘿,别生气啊,不过真的谢谢你,shell脚本的编写也学会了不少东西
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP