我在 bash 脚本中有以下几行:
while true; do
DATE=date
FORMAT="%Y%m%d"
read -p "Enter start date (YYYYMMDD) " STARTDATE
if date=$(date -d "$STARTDATE" +'+%Y%m%d'); then
start_date=`$DATE +$FORMAT -d $STARTDATE`
echo $start_date
break
fi
echo "Please use right format (YYYYMMDD) "
done
只要输入是 8 个数字,它就可以正常工作(例如,它接受“20210901”并拒绝“20213131”)。然而,当输入完全关闭时(例如“a”或“废话”),它只需要今天的日期。如何修改代码以更严格地检查格式?
修改后的代码如下:
valid=0
while true; do
DATE=date
FORMAT="%Y%m%d"
read -p "Enter start date (YYYYMMDD) " initialdate
if date=$(date -d "$initialdate" +'+%Y%m%d'); then
start_date=`$DATE +$FORMAT -d $initialdate`
if [[ "$start_date" =~ ^[[0123456789]]{8}$ ]]
then
valid=1
echo "valid";
echo $start_date
break
else
echo "Invalid format"
fi
fi
echo "Please use right format (YYYYMMDD) "
done
由于您可以将任务简化为要求输入恰好包含 8 位数字的额外检查,并且您正在使用 Bash,因此您可以利用正则表达式比较运算符:
这将检查 的内容是否
$startdate
符合由八位数字组成的正则表达式。您可以将其组合如下:
作为基本规则:
shellcheck
,也可作为许多 Linux 发行版上的独立程序使用,以验证您的 shell 脚本。$PATH
意外覆盖关键设置。进行输入验证的一种常见方法是使用一个无限循环,一旦输入被验证,您就会中断该循环。
在这种情况下,“已验证”意味着输入字符串仅包含八位数字,并且 GNU
date
能够使用该日期作为其-d
选项的选项参数。,
bash
我们可以把它写成这会在循环开始时读取日期,然后使用正则表达式对其进行测试,如果字符串仅包含八位数字,该正则表达式将匹配。如果该测试通过,该字符串也将使用 GNU 进行测试
date
。如果一切顺利,则通过break
语句退出循环。在
sh
中,我们需要将正则表达式匹配替换为 shell 模式匹配:这里的测试首先测试字符串是否包含除数字之外的任何其他字符。如果该测试失败,则下一个测试正好是八个字符。如果该测试成功,我们有一个八位数字的字符串,我们使用 GNU 进行测试,
date
如果日期正常则退出循环。或者没有无限循环,并假设 BSD 的
date(1)
命令:${REPLY}0000
语法是必要的,因为 BSD想要date
一个完整的 YmdHM,但默认 HM0000
就足够了。