Answers:
您可以使用测试构造[[ ]]以及正则表达式匹配运算符=~来检查字符串是否与正则表达式模式匹配。
对于您的特定情况,您可以编写:
[[ $date =~ ^[0-9]{8}$ ]] && echo "yes"
或更准确的测试:
[[ $date =~ ^[0-9]{4}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])$ ]] && echo "yes"
# |^^^^^^^^ ^^^^^^ ^^^^^^ ^^^^^^ ^^^^^^^^^^ ^^^^^^ |
# | | ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ |
# | | | | |
# | | \ | |
# | --year-- --month-- --day-- |
# | either 01...09 either 01..09 end of line
# start of line or 10,11,12 or 10..29
# or 30, 31
也就是说,您可以在Bash中定义与所需格式匹配的正则表达式。这样,您可以执行以下操作:
[[ $date =~ ^regex$ ]] && echo "matched" || echo "did not match"
其中命令之后&&被执行,如果测试是成功的,和命令之后||,如果测试不成功被执行。
请注意,这是基于Aleks-Daniel Jakimenko 在bash中的用户输入日期格式验证中的解决方案。
在其他Shell中,可以使用grep。如果您的外壳符合POSIX,请执行
(echo "$date" | grep -Eq ^regex$) && echo "matched" || echo "did not match"
在不符合POSIX的fish中,您可以执行
echo "$date" | grep -Eq "^regex\$"; and echo "matched"; or echo "did not match"
grep带有-Eflag的命令更容易理解regex的bash语法。
sh,则使用grep的@ Aleks-DanielJakimenko似乎是最佳选择fish。
在bash版本3中,您可以使用'=〜'运算符:
if [[ "$date" =~ ^[0-9]{8}$ ]]; then
echo "Valid date"
else
echo "Invalid date"
fi
参考:http : //tldp.org/LDP/abs/html/bashver3.html#REGEXMATCHREF
注意:从Bash版本3.2开始,不再需要在双括号[[]]中使用匹配运算符的引号
测试字符串是否正确的日期的一种好方法是使用命令date:
if date -d "${DATE}" >/dev/null 2>&1
then
# do what you need to do with your date
else
echo "${DATE} incorrect date" >&2
exit 1
fi
摘自评论:可以使用格式
if [ "2017-01-14" == $(date -d "2017-01-14" '+%Y-%m-%d') ]
date -d 2017-11-14e它将返回UTC 2017 Tue Nov 14 05:00:00 UTC,但这会破坏我的脚本。
我会使用expr match而不是=~:
expr match "$date" "[0-9]\{8\}" >/dev/null && echo yes
这比当前接受的使用方法更好,=~因为它=~还会匹配空字符串,恕我直言,它不应该。假设badvar未定义,则[[ "1234" =~ "$badvar" ]]; echo $?给出(不正确)0,而expr match "1234" "$badvar" >/dev/null ; echo $?给出正确的结果1。
我们必须使用>/dev/nullhide expr match的输出值,它是匹配的字符数,如果找不到匹配的则为0。请注意,其输出值与退出状态不同。如果找到匹配项,则退出状态为0,否则为1。
通常,的语法为expr:
expr match "$string" "$lead"
要么:
expr "$string" : "$lead"
$lead正则表达式在哪里。它的exit status将是真正的(0),如果lead匹配的领先的切片string(是否有此名字吗?)。例如,expr match "abcdefghi" "abc"退出true,但expr match "abcdefghi" "bcd"退出false。(@Carlo Wood指出了这一点。
=~不匹配空字符串,则在给出的示例中将字符串与空模式匹配。语法为string =~ pattern,并且空模式匹配所有内容。
expr match "abcdefghi" "^" && echo Matched || echo No match-和expr match "abcdefghi" "bcd" && echo Matched || echo No match-都返回"0\nNo match"。匹配"a.*f"将返回的位置"6\nMatched"。因此,在您的示例中也不需要使用'^',并且已经暗示了该含义。
=~匹配空字符串的行为。这是因为此行为可能是意外的,并且可能导致错误。我之所以写这个答案,是因为我被它烧死了。
expr同意我的观点。
如果使用正则表达式有助于确定日期的字符序列是否正确,则不能轻易使用它来确定日期是否有效。以下示例将传递正则表达式,但所有日期均无效:20180231、20190229、20190431
因此,如果您想验证日期字符串(让我们称之为datestr)是否采用正确的格式,则最好使用它进行解析,date并要求date将其转换为正确的格式。如果两个字符串相同,则您具有有效的格式和有效的日期。
if [[ "$datestr" == $(date -d "$datestr" "+%Y%m%d" 2>/dev/null) ]]; then
echo "Valid date"
else
echo "Invalid date"
fi