我在if-else块中定义匹配的模式是:
php artisan cache:clear
php artisan config:clear
php artisan view:clear
在我的脚本中,我正在接收需要与模式匹配的用户输入,如果不匹配,则会显示相应的错误消息。很简单,但给我一个艰难的时间。我在脚本中的代码块是:
pat="17[0-1][0-9][0-9][0-9].AUG"
nln=""
我希望用户输入要输入的文件名的格式为:
echo "How many days' AUDIT Logs need to be searched?"
read days
echo "Enter file name(s)[For multiple files, one file per line]: "
for(( c = 0 ; c < $days ; c++))
do
read elements
if [[ $elements =~ $pat ]];
then
array[$c]="$elements"
elif [[ $elements =~ $nln ]];
then
echo "No file entered.Run script again. Exiting"
exit;
else
echo "Invalid filename entered: $elements.Run script again. Exiting"
exit;
fi
done
所以基本上yymmdd.AUG(y年,月,日),尾随或前导空格都可以。除此之外的任何内容都应该抛出170402.AUG
消息。另外,我想检查一下如果它是一个带有“回车”命中的空行,它应该会出错"Invalid filename entered: $elements.Run script again. Exiting"
然而,我的代码,即使我输入类似“xxx”的文件名,应该抛出"No file entered.Run script again. Exiting"
,实际上是对空行检查为true,并抛出"Invalid filename entered: $elements.Run script again. Exiting"
需要一些帮助来处理正则表达式的用户输入检查,否则我的脚本的其余部分工作正常。
答案 0 :(得分:3)
我认为正如评论中所讨论的那样,您对 glob 匹配和regEx
匹配感到困惑,您定义为pat
的是一个需要的全局匹配等同于==
运算符,
pat="17[0-1][0-9][0-9][0-9].AUG"
string="170402.AUG"
[[ $string == $pat ]] && printf "Match success\n"
等效~
匹配将是
pat="17[[:digit:]]{4}\.AUG"
[[ $string =~ $pat ]] && printf "Match success\n"
正如您所看到的,正则表达式语法中的.
已被转义为剥夺其特殊含义(匹配任何字符),但仅用作文字点。带有字符数POSIX
的{{1}}字符类[[:digit:]]
可让您匹配{4}
后跟4
对于字符串空检查,请按照Cyrus或Benjamin.W的评论建议
.AUG
(或)
[[ $elements == "" ]]
答案 1 :(得分:2)
我不会用how many days
(想要数15天或类似的人)来欺骗用户?另外,为什么每行只有一个文件?你应该帮助用户,而不是像微软那样弄错他们......
首先:
show_help() { cat <<'EOF'
bla bla....
EOF
}
show_files() { echo "${#files[@]} valid files entered: ${files[@]}"; }
while read -r -p 'files? (h-help)> ' line
do
case "$line" in
q) echo "quitting..." ; exit 0 ;;
h) show_help ; continue;;
'') (( ${#files} )) && show_files; continue ;;
l) show_files ; continue ;;
p) (( ${#files} )) && break || { echo "No files enterd.. quitting" ; exit 1; } ;; # go to processing
esac
# select (grep) the valid patterns from the entered line
# and append them into the array
# using the -P (if your grep know it) you can construct very complex regexes
files+=( $(grep -oP '17\d{4}.\w{3}' <<< "$line") )
done
echo "processing files ${files[@]}"
使用这样的逻辑,您可以构建功能强大且用户友好的应用程序。此外,您可以-e
使用read
启用readline
功能(光标键等)......
但是 :)考虑只创建一个接受参数的简单脚本。没有任何对话等。例如:
myscript -h
与上述相同,或更长的帮助文本
myscript 170402.AUG 170403.AUG 170404.AUG 170405.AUG
将对文件做任何事情。主要的好处是,你可以在文件名中使用globbing,比如
myscript 1704*
依旧......
如果你真的想要这个对话框,它可以在没有任何参数的情况下运行脚本时显示它,例如:
myscript
将以交互模式运行......