我试图在while语句中编写一个不区分大小写的比较。基本上,我只是想缩短以下内容,以便对用户的“是”或“否”问题提示进行操作...
while[ $yn == "y" | $yn == "Y" | $yn == "Yes" | $yn == "yes" ] ; do
如何最好地解决这个问题?
不需要使用shopt或正则表达式。如果您有Bash 4,最简单、最快的方法是:
if [ "${var1,,}" = "${var2,,}" ]; then
echo "matched"
fi
你所做的只是将两个字符串转换为小写并比较结果。
${my_variable,,}
语法是 Bash 参数扩展。请参阅 https://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion 并滚动到该部分底部以获取大小写转换的信息。 - Riotshopt -s nocasematch
while [[ $yn == y || $yn == "yes" ]] ; do
或:shopt -s nocasematch
while [[ $yn =~ (y|yes) ]] ; do
[[
是类似于(但比)[
命令更强大的bash关键字。请参见 http://mywiki.wooledge.org/BashFAQ/031 和 http://mywiki.wooledge.org/BashGuide/TestsAndConditionals。
除非你是为 POSIX sh 编写,否则我们建议使用 [[
。[[
的 =~
运算符会将左侧字符串与右侧扩展正则表达式(ERE)进行匹配评估。在成功匹配后,BASH_REMATCH
可用于扩展模式中匹配的组。引用了正则表达式的部分将变成文字。为了安全和兼容,请将正则表达式放入参数中,然后执行 [[ $string =~ $regex ]]
。shopt -s nocasematch
会使我的基于sed的查找和替换也不区分大小写吗? - user2150250^..$
,例如 yn="noyesno"
。 - Kentwhile[[ $yn =~ (y|yes) ]]
似乎完美地工作了。 - user2150250[[ $yn =~ y(es)? ]]
;顺便说一下,(y|yes)
中的括号并不是必需的。 - Benjamin W.以下是使用扩展模式而不是正则表达式的答案:
shopt -s nocasematch
shopt -s extglob
while [[ $yn = y?(es) ]]; do
...
done
bash
在 [[ ... ]]
条件表达式内始终使用扩展模式,因此不需要添加 shopt
行。y
匹配它本身;?(es)
匹配模式es
的零个或一个实例。 - chepner我更喜欢使用grep -E
或简称egrep
:
while egrep -iq '^(y|yes)$' <<< $yn; do
your_logic_here
done
以下是来自 grep
手册的解释:
-i,--ignore-case
忽略模式和输入文件中的大小写区别。(-i由POSIX指定。)
-q,--quiet,--silent
安静模式;不向标准输出写入任何内容。即使检测到错误,如果找到任何匹配项,立即以零状态退出。也请参阅-s或--no-messages选项。(-q由POSIX指定。)
try this one too:
[[ $yn =~ "^[yY](es)?$" ]]
[[ $yn =~ "^[yY][eE][sS]" || $yn == [yY] ]]
。我希望能够接受 "yEs"、"YeS" 和所有其他大小写组合。 - user2150250y
是不区分大小写的,es
部分只能小写... 这是我理解的。 - Kentyn=${yn,,}; [[ $yn =~ ^yes ]]
- Bruce[[ ]]
中使用它,不要加引号。 - Benjamin W.
[
之前缺少一个空格。 - Benjamin W.