测试参数看起来像日期

问题描述 投票:0回答:1

我正在修改用于测试报告编写者的脚本。报表编写器采用可选的--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 $1 | grep -e '[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]')
    echo from -
    echo \$1: \"$1\"
    echo looksLikeDate: \"$looksLikeDate\"
    if [ -n $looksLikeDate ]
    then
        echo "-n: true"
        FROMFLAG="--from $1"
        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 $1 | grep -e '[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]')
    echo to -
    echo \$1: \"$1\"
    echo looksLikeDate: \"$looksLikeDate\"
    if [ -n $looksLikeDate ]
    then
        echo "-n: true"
        TOFLAG="--to $1"
        shift 1
    else
        echo "-n: false"
        TOFLAG=""
    fi

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

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

...并且没有...

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

...我错过了什么?我希望由于looksLikeDate可显示为空,因此[ -n $looksLikeDate ]将返回false,并且代码将沿着else语句的if路径运行。

更新:

[自发布以来,我发现最简单的方法是不查看函数中的参数,而是让调用者将--from--to与参数一起传递,以便我可以简单地将$*传递给报告编写器,就像对现有可选参数所做的一样。

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

regex bash cygwin
1个回答
1
投票

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

所以这就是正在发生的事情:当Bash看到

[ -n $looksLikeDate ]

它执行参数扩展,全局扩展,引用删除等,最后看到了这一点(我在每一行上放了一个令牌):

[
-n
]

并且您会看到缺少$looksLikeDate部分,因为参数$looksLikeDate在引号删除步骤之前扩展为空字符串。然后Bash执行内置的[,并以结束]等效于以下命令:

test -n

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

1个论点

[且仅当参数不为null时,表达式为true。

这里,参数是test,因此不是nil,因此表达式为true。

所以请记住:

使用更多引号!引用all您的变量扩展!

此特定行应如下所示:

-n

另一种可能性是使用[ -n "$looksLikeDate" ] 关键字:

[[

但是无论如何,请引用您的所有扩展!

而且,您不需要外部工具[[ -n $looksLikeDate ]] ,可以使用Bash的内部正则表达式引擎,或者更好的是:

grep

有点长,所以使用变量:

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

((这里您必须引用右侧date_pattern="[[:digit:]][[:digit:]]/[[:digit:]][[:digit:]]/[[:digit:]][[:digit:]][[:digit:]][[:digit:]]" if [[ $1 = $date_pattern ]]; then )。

© www.soinside.com 2019 - 2024. All rights reserved.