我的脚本收到的一个参数是以下格式的日期:yyyymmdd
。
我想检查一下是否有一个有效的日期作为输入。
我该怎么做?我正在尝试使用像[0-9]\{\8}
答案 0 :(得分:246)
你可以说:
[[ $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在User input date format verification in bash中的解决方案。
在其他shell中,您可以使用 grep 。如果您的shell符合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"
答案 1 :(得分:38)
在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起,不再需要在双括号[[]]内的匹配运算符中引用
答案 2 :(得分:27)
测试字符串是否正确日期的好方法是使用命令日期:
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
答案 3 :(得分:1)
我将使用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
隐藏expr match
的输出值,即匹配的字符数;如果找不到匹配的字符,则返回0。请注意,其输出值与它的退出状态不同。如果找到匹配项,则退出状态为0,否则为1。
通常,expr
的语法为:
expr match "$string" '$substring'
或者:
expr "$string" : '$substring'
其中$substring
是一个正则表达式。
答案 4 :(得分:0)
使用正则表达式可以帮助确定日期的字符序列是否正确,但不能轻松地使用它来确定日期是否有效。以下示例将传递正则表达式,但均为无效日期: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
答案 5 :(得分:0)
除了 =~
Bash 运算符的其他答案 - Extended Regular Expressions (ERE)。
这是awk
和egrep
(或grep -E
)使用的语法,
以及 Bash 的 [[ ... =~ ... ]]
运算符。
例如,支持多个参数提供的多个测试的函数:
#!/bin/bash
#-----------#
# Functions #
#-----------#
function RT
{
declare line_l;
for line_l in "${@:2}";
do
if ! [[ "$line_l" =~ $1 ]];
then
return 1;
fi
done
return 0;
}
#-----------#
# Main #
#-----------#
regex_v='^[0-9]*$';
value_1_v='12345';
value_2_v='67890';
if RT "$regex_v" "$value_1_v" "$value_2_v";
then
printf 'Valid';
else
printf 'Invalid';
fi
RT
或 Regex Test
# Declare a local variable for a loop.
declare line_l;
# Loop for every argument's value except the first whish is a regex rule
for line_l in "${@:2}";
# Test the value and return a **non-zero** return code if failed
if ! [[ "$line_l" =~ $1 ]];
# Return a **zero** return code - success.
return 0;
# Define arguments for the function to test
regex_v='^[0-9]*$'; # Regex rule
value_1_v='12345'; # First value
value_2_v='67890'; # Second value
# A statement which runs the function with specified arguments
# and executes `printf 'Valid';` if succeeded, else - `printf 'Invalid';`
if RT "$regex_v" "$value_v";
应该可以指向失败的参数,例如,通过在循环中附加一个计数器并将其值打印到 stderr
。
=~
运算符右侧的引号使其成为字符串,而不是 RegularExpression。< /p>