Poo*_*nam 3 shell-script regular-expression
我试图抑制 date 命令生成的错误,但执行脚本后仍然出现错误。
#!/usr/bin/bash
input="30 FEB 2022"
reg="^[0-9]{1,2}\s[a-zA-Z]{1,3}\s[0-9]{1,4}$"
if [[ $input =~ $reg ]]
then
echo "VALID Date Format : $input"
#output=$(`date -d "$input" +"%d-%b-%Y, %A"` 2>&1 > /dev/null)
output=`date -d "$input" +"%d-%b-%Y, %A"` 2>&1 > /dev/null
else
echo "INVALID Date Format : $input"
output="-1"
fi
echo $output
Run Code Online (Sandbox Code Playgroud)
执行后输出 -
root@ip-xx-x-xx-xxx:~# ./exDate.sh
VALID Date Format : 30 FEB 2022
date: invalid date '30 FEB 2022'
Run Code Online (Sandbox Code Playgroud)
请告知我如何抑制错误?
您已经得到了答案,为您提供了更好的方法,所以我只回答您提出的问题。您仍然看到错误消息的原因是重定向的顺序很重要。重定向是从左到右读取的,因此2>&1 > /dev/null意味着“首先将 stderr 重定向到 stdout,然后将 stdout 重定向到/dev/null”。这意味着您的错误将被打印到标准输出,并且正常的标准输出将被重定向到/dev/null. 您可以通过将 stdout 管道传输到以下命令来看到这一点wc:
## No redirection\n$ date -d foo \ndate: invalid date \xe2\x80\x98foo\xe2\x80\x99\n\n## Nothing is printed to stdout, the error goes to stderr\n## and wc has nothing to count\n$ date -d foo | wc\ndate: invalid date \xe2\x80\x98foo\xe2\x80\x99\n 0 0 0\n\n## Redirect using 2>&1 > /dev/null\n$ date -d foo 2>&1 > /dev/null\ndate: invalid date \xe2\x80\x98foo\xe2\x80\x99\n\n## The error is now being printed to stdout, wc counts it\n$ date -d foo 2>&1 > /dev/null | wc\n 1 4 29\nRun Code Online (Sandbox Code Playgroud)\n您想要的是将 stdout 重定向到/dev/null第一个,然后将 stderr 重定向到 stdout: > /dev/null 2>&1。这行为如您所愿:
$ date -d foo > /dev/null 2>&1 \n$ \nRun Code Online (Sandbox Code Playgroud)\n
您无法使用正则表达式或模式验证日期。(好吧,我想你也许可以这样做,但那会很不愉快。)
\n相反,使用date命令本身来验证输入。将此脚本写入文件exDate并使其可执行(chmod a+x exDate ):
#!/bin/bash\n\ninput=$1\nif date --date "$input" >/dev/null 2>&1\nthen\n # Good date\n output=$(date --date "$input" +'%d-%b-%Y, %A')\nelse\n # Date parsing failed\n printf 'INVALID Date Format : %s\\n' "$input" >&2\n output='-1'\nfi\n\nprintf "%s\\n" "$output"\nRun Code Online (Sandbox Code Playgroud)\n运行示例
\n./exDate '30 FEB 2022'\nINVALID Date Format : 30 FEB 2022\n-1\n\n./exDate '24 FEB 2022'\n24-Feb-2022, Thursday\n\n./exDate '2022-04-13'\n13-Apr-2022, Wednesday\nRun Code Online (Sandbox Code Playgroud)\n如果最后一个选项不可接受(即您只想接受表单中的日期d(d) MMM yyyy),那么您需要进行模式匹配以及使用date来验证:
if [[ "$input" =~ ^[0-9]{1,2}\\ [a-zA-Z]{3}\\ [0-9]{4}$ ]] && date\xe2\x80\xa6\nthen\nRun Code Online (Sandbox Code Playgroud)\nif date...您可以将与分配合并output=,从而简化代码,然后只需要处理失败情况:
if ! output=$(date --date "$input" +'%d-%b-%Y, %A' 2>/dev/null)\nthen\n # Date parsing failed\n printf 'INVALID Date Format : %s\\n' "$input" >&2\n output='-1'\nfi\nRun Code Online (Sandbox Code Playgroud)\n