测试该参数看起来像一个日期

test that argument looks like a date

我正在修改用于测试报告编写器的脚本。报告作者采用可选的 --from 和 --to 标志来指定开始和结束日期。我想修改启动报告编写器的脚本函数,使其日期参数也是可选的。

遗憾的是,该函数已经有可选参数,因此我正在尝试测试参数是否采用正确的日期格式(我们使用 nn/nn/nnnn)。

因此,我正在回显候选字符串并使用 grep 检查它的格式是否正确。除非它不起作用。

这是函数的摘录

    # If the next argument looks like a date, consume it and use it to define
    # the report start date

    looksLikeDate=$(echo  | grep -e '[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]')
    echo from -
    echo $1: \"\"
    echo looksLikeDate: \"$looksLikeDate\"
    if [ -n $looksLikeDate ]
    then
        echo "-n: true"
        FROMFLAG="--from "
        shift 1
    else
        echo "-n : false"
        FROMFLAG=""
    fi

    # If the next argument looks like a date, consume it and use it to define
    # the report end date

    looksLikeDate=$(echo  | grep -e '[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]')
    echo to -
    echo $1: \"\"
    echo looksLikeDate: \"$looksLikeDate\"
    if [ -n $looksLikeDate ]
    then
        echo "-n: true"
        TOFLAG="--to "
        shift 1
    else
        echo "-n: false"
        TOFLAG=""
    fi

...这是带日期的输出...

from -
: "09/02/2018"
looksLikeDate: "09/02/2018"
-n: true
to -
: "09/02/2018"
looksLikeDate: "09/02/2018"
-n: true

...并且没有...

from -
: ""
looksLikeDate: ""
-n: true
to -
: ""
looksLikeDate: ""
-n: true

...我错过了什么?我希望因为 looksLikeDate 是可证明的空 [ -n $looksLikeDate ] 会 return false 并且代码会沿着 ifelse 路径声明。

更新:

自发布以来,我想到最简单的事情就是不查看函数中的参数并让调用者将 --from--to 与参数一起传递,这样我可以简单地将 $* 传递给报告作者,就像对现有可选参数所做的那样。

非常感谢您的阅读;我仍然很好奇为什么发布的代码不起作用。

那是因为你没有引用你的变量! Use more quotes!

事情是这样的:当 Bash 看到

[ -n $looksLikeDate ]

它进行了参数展开,glob展开,去掉引号等等,最后看到这个(我每行放一个token):

[
-n
]

你会看到缺少 $looksLikeDate 部分,因为参数 $looksLikeDate 在引号删除步骤之前扩展为空字符串。然后Bash执行内建[,加上关闭],相当于下面的命令:

test -n

现在查看 reference manual for the test builtin,您将阅读:

1 argument

The expression is true if, and only if, the argument is not null.

在这里,参数是 -n,因此不为零,因此表达式为真。

所以请记住:

Use more quotes! quote all your variable expansions!

此特定行应如下所示:

[ -n "$looksLikeDate" ]

另一种可能是使用[[关键字:

[[ -n $looksLikeDate ]]

但无论如何,引用你所有的扩展!

此外,您不需要外部工具 grep,您可以使用 Bash 的内部正则表达式引擎,或者,更好的是:

if [[  = [[:digit:]][[:digit:]]/[[:digit:]][[:digit:]]/[[:digit:]][[:digit:]][[:digit:]][[:digit:]] ]]; then

有点长,所以用一个变量:

date_pattern="[[:digit:]][[:digit:]]/[[:digit:]][[:digit:]]/[[:digit:]][[:digit:]][[:digit:]][[:digit:]]"
if [[  = $date_pattern ]]; then

(这里你不能引用右边的$date_pattern)。