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
带有-E
flag的命令更容易理解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/null
hide 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