测试该参数看起来像一个日期
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
并且代码会沿着 if
的 else
路径声明。
更新:
自发布以来,我想到最简单的事情就是不查看函数中的参数并让调用者将 --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
)。
我正在修改用于测试报告编写器的脚本。报告作者采用可选的 --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
并且代码会沿着 if
的 else
路径声明。
更新:
自发布以来,我想到最简单的事情就是不查看函数中的参数并让调用者将 --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
)。