我们可以在 Bash case 语句中使用正则表达式吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7758704/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can we use regular expressions In Bash case statements?
提问by Ashley Raiteri
I was digging through mysql_safe (trying to add some options) and I came across this bash scripting technique they use to assign variables from the Launch Agent: com.mysql.mysqld.plist (I'm on a mac).
我正在挖掘 mysql_safe(试图添加一些选项),我遇到了他们用来从 Launch Agent 分配变量的 bash 脚本技术:com.mysql.mysqld.plist(我在 mac 上)。
Now mysqld_safe doesn't know it's being invoked by LaunchCtl, so I assume any options are converted by LaunchCtl into command line arguments, but I found this sytnax intruiging. Anyone know how this works?
现在 mysqld_safe 不知道它正在被 LaunchCtl 调用,所以我假设 LaunchCtl 将任何选项转换为命令行参数,但我发现这个 sytnax 很有趣。有谁知道这是如何工作的?
I understand the basics of Case/Switch in Bash:
我了解 Bash 中 Case/Switch 的基础知识:
case "$myval" in
switch1) do something;;
switch2) do something;;
*) do whatever fallthrough logic;;
esac
with the default fall through using *
In the script chunk below, the arg value is:
"--basedir=" or "--datadir=" or "--pid-file=", etc
But WHAT IS UP WITH THE * in there?
Is that a Regular Expression in Switch Statement??
WITH A BACKREFERENCE?
默认情况下使用 * 在下面的脚本块中,arg 值为:“--basedir=”或“--datadir=”或“--pid-file=”等但是 * 在那里?
那是 Switch 语句中的正则表达式吗??
有反向引用?
for arg do
# the parameter after "=", or the whole $arg if no match
val=`echo "$arg" | sed -e 's;^--[^=]*=;;'`
# what's before "=", or the whole $arg if no match
optname=`echo "$arg" | sed -e 's/^\(--[^=]*\)=.*$//'`
# replace "_" by "-" ; mysqld_safe must accept "_" like mysqld does.
optname_subst=`echo "$optname" | sed 's/_/-/g'`
arg=`echo $arg | sed "s/^$optname/$optname_subst/"`
arg=`echo $arg | sed "s/^$optname/$optname_subst/"`
case "$arg" in
# these get passed explicitly to mysqld
--basedir=*) MY_BASEDIR_VERSION="$val" ;;
--datadir=*) DATADIR="$val" ;;
--pid-file=*) pid_file="$val" ;;
--plugin-dir=*) PLUGIN_DIR="$val" ;;
--user=*) user="$val"; SET_USER=1 ;;
...
...
*)
if test -n "$pick_args"
then
append_arg_to_args "$arg"
fi
;;
esac
回答by Keith Thompson
They aren't regular expressions; they're filename expansion patterns, also known as "globs".
它们不是正则表达式;它们是文件名扩展模式,也称为“globs”。
*matches zero or more arbitrary characters, and ?matches any single character.
*匹配零个或多个任意字符,并?匹配任何单个字符。
For more information: http://www.gnu.org/s/bash/manual/bash.html#Pattern-Matching
更多信息:http: //www.gnu.org/s/bash/manual/bash.html#Pattern-Matching
回答by glenn Hymanman
If you have a recent version bash, you can use real regular expressions to parse the arg, and the access the bash array BASH_REMATCH for the captured groups:
如果您有最新版本的 bash,您可以使用真正的正则表达式来解析 arg,并访问捕获组的 bash 数组 BASH_REMATCH:
for arg; do
if [[ $arg =~ ^--([^=]+)=(.*) ]]; then
optname=${BASH_REMATCH[1]}
val=${BASH_REMATCH[2]}
optname_subst=${optname//_/-}
case "$optname" in
basedir) MY_BASEDIR_VERSION="$val" ;;
datadir) DATADIR="$val" ;;
...
esac
else
do something with non-option argument
fi
done

