如何用正则从字符串提取环境变量名与值?Bash脚本适配问题
问题描述
给定字符串:
str='-e ENV_PASSWORD="foo" -e ENV_USER="bar-e sd" -e ENV_DB_NAME="mysite_staging" '
需要通过Bash脚本把其中的环境变量名(比如ENV_PASSWORD)和对应值(比如foo)分别提取出来,存到不同变量里。已经用Python 3实现了这个功能,但把相同的正则表达式放到grep里却没法正常工作,求Bash下的可行方案。
Python 3实现示例
python_test.py代码:
import re target_str = '-e ENV_PASSWORD="foo" -e ENV_USER="bar-e sd" -e ENV_DB_NAME="mysite_staging" ' pattern = r'-e (\w+)="([^"]*)"' matches = re.findall(pattern, target_str) for name, value in matches: print(f"变量名: {name}, 值: {value}")
输出:
变量名: ENV_PASSWORD, 值: foo 变量名: ENV_USER, 值: bar-e sd 变量名: ENV_DB_NAME, 值: mysite_staging
常见的Bash失败尝试(bash_test.sh)
很多人会直接用grep的-o选项,但默认grep不会单独输出正则分组,只会返回整段匹配内容:
str='-e ENV_PASSWORD="foo" -e ENV_USER="bar-e sd" -e ENV_DB_NAME="mysite_staging" ' grep -Eo '-e (\w+)="([^"]*)"' <<< "$str"
输出只会是整段的匹配项,没法拆分变量名和值。
Bash下的解决方法
方法1:grep+sed组合提取分组
先用grep找出所有匹配项,再用sed拆分变量名和值:
str='-e ENV_PASSWORD="foo" -e ENV_USER="bar-e sd" -e ENV_DB_NAME="mysite_staging" ' grep -Eo '-e \w+="[^"]*"' <<< "$str" | while read -r match; do # 提取变量名 var_name=$(sed -E 's/-e (\w+)="[^"]*"/\1/' <<< "$match") # 提取变量值(自动去掉引号) var_value=$(sed -E 's/-e \w+="([^"]*)"/\1/' <<< "$match") echo "变量名: $var_name, 值: $var_value" # 如果要直接设置环境变量,执行这句:export "$var_name=$var_value" done
输出和Python版本完全一致。
方法2:Bash内置正则匹配(无外部工具)
Bash 3.2及以上版本支持内置正则匹配,直接用[[ ]]和=~循环提取,效率更高:
str='-e ENV_PASSWORD="foo" -e ENV_USER="bar-e sd" -e ENV_DB_NAME="mysite_staging" ' pattern='-e ([[:alnum:]_]+)="([^"]*)"' # 循环匹配所有项,直到字符串处理完 while [[ "$str" =~ $pattern ]]; do var_name="${BASH_REMATCH[1]}" var_value="${BASH_REMATCH[2]}" echo "变量名: $var_name, 值: $var_value" # 移除已经匹配过的部分,继续处理剩余字符串 str="${str#*"${BASH_REMATCH[0]}"}" done
方法3:awk一次性拆分
用awk按分隔符拆分字符串,直接提取变量名和值:
str='-e ENV_PASSWORD="foo" -e ENV_USER="bar-e sd" -e ENV_DB_NAME="mysite_staging" ' awk -F' -e ' '{ for (i=2; i<=NF; i++) { split($i, arr, /="/) var_name = arr[1] var_value = substr(arr[2], 1, length(arr[2])-1) # 去掉结尾的引号 print "变量名: " var_name ", 值: " var_value } }' <<< "$str"
内容的提问来源于stack exchange,提问作者Jeetu
相关产品推荐
相关产品推荐

