月份日不是整数

时间:2015-11-01 03:00:29

标签: bash date

我正在调整a bash script of mine以输出一个月中某一天的序数部分(st,nd,rd,th)。我正在尝试调整它以在date命令中的日期模式中使用。

这是一个简单的测试,用于确定date命令中的某一天是否为int:

dayOfMonth=$(date +"%d") && [[ ${dayOfMonth} =~ ^[0-9]+$ ]] && echo ${dayOfMonth} is an int || echo ${dayOfMonth} is NOT an int

输出正如我所料

01 is an int

现在我将该代码放入脚本中:

#!/bin/bash
[[ ${1} =~ ^[0-9]+$ ]] && echo ${1} is an int || echo ${1} is NOT an int

似乎没问题:

dateTest.sh 12
12 is an int

但是当我尝试在date命令中使用它时,脚本给了我相互矛盾的输出。 echo看到12,但测试看到%2

date --date='06/12/2012 07:21:22' +"`dateTest.sh %d`"
12 is NOT an int

为了澄清我的目的,脚本的最终结果将是这样的:

#!/bin/bash
n=$(date +"%d")

if [ $# -ge 1 ] ; then
   n=$1
   if ! [[ $n =~ ^[0-9]+$ ]] ; then
      echo Arg dateInteger [$dateInteger] must be an integer.
      exit 1
   fi
fi

if [ $n -ge 11 -a $n -le 13 ] ; then
  echo "th"
else
 case $(( $n%10 )) in
 1)
   echo st
   ;;
 2)
   echo nd
   ;;
 3)
   echo rd
   ;;
 *)
   echo th
   ;;
 esac
fi

所以我可以这样:

date --date='06/12/2012 07:21:22' +"%A, %d`dateTest.sh %d` of %B %Y, %I:%M:%S %p"

将输出

Tuesday, 12th of June 2012, 07:21:22 AM

完成的脚本重写。感谢@GordonDavisson的输入,我完成了我的脚本重写:http://pastebin.com/xZ1afqqC。现在它只输出一个整数的序数,或输出一个完全格式化的日期,你可以使用date中的标准格式字符串添加"%O"对于序数。

1 个答案:

答案 0 :(得分:3)

你正在以错误的顺序做事 - 你必须将“%d”变成一个整数(月中的某一天),然后再将传递给你的脚本,而不是之后。考虑命令:

date --date='06/12/2012 07:21:22' +"`dateTest.sh %d`"

这样做是运行dateTest.sh %d,即它将“%d”作为参数传递给您的脚本。该脚本自然输出“%d不是int”。然后将其用作date命令的格式字符串,即date --date='06/12/2012 07:21:22' +"%d is not an int"date命令用“天数”替换“%d”部分,其余部分单独留下,给出“12不是int”。

为了完成这项工作,您必须先获取日期编号,然后将其传递给您的脚本。像这样:

dateTest.sh "$(date --date='06/12/2012 07:21:22' +"%d")"

不幸的是,您的最终结果脚本还需要完成一堆其他日期格式化,无法传递给dateTest脚本。我认为在这种情况下,最好分阶段进行:

dayWithSuffix="$(dateTest.sh "$(date --date='06/12/2012 07:21:22' +"%d")")"
date --date='06/12/2012 07:21:22' +"%A, $dayWithSuffix of %B %Y, %I:%M:%S %p"
BTW,几个一般的脚本建议:

  • 将错误/调试输出发送到stderr,而不是stdout,因此它不会与脚本的常规输出混淆(这里的部分问题)。例如,echo "${1} is NOT an int" >&2

  • 说到这一点,将包含变量的字符串放在双引号中(就像我在上一个例子中所做的那样),以避免奇怪的空格,通配符等的错误分析。例如,结果脚本包含{{1 - 您可能没有意识到在某些情况下echo Arg dateInteger [$dateInteger] must be an integer.部分将被文件名列表替换。

  • 最后,使用[$dateInteger]代替反引号。在大多数情况下,它们是等价的,但括号版本更容易阅读,并避免了一些奇怪的解析内容的奇怪。请注意我如何在赋值$( ... )中嵌套两个这样的表达式?用反引号来纠正是比较棘手的。