如何用正则匹配类Shell兼容的环境变量赋值并提取键值对
如何匹配并提取CentOS /etc/locale.conf中的变量键值对
我经常帮人处理系统配置文件的解析问题,针对CentOS里/etc/locale.conf的变量赋值语句——不管是像LANG="en_US.UTF-8"、LANG=en_US.UTF-8还是LANG='en_US.UTF-8'这类格式,都可以用一套简洁的方案来匹配并提取键名和对应的值。下面我分享几种实用的方法:
核心匹配逻辑:正则表达式
首先要明确符合要求的赋值语句的特征:
- 行首是大写字母+下划线组成的键名(比如
LANG、LC_TIME) - 等号前后可以有任意空格
- 值可以带单/双引号,也可以不带,且引号必须成对
对应的正则表达式是:
^([A-Z_]+)\s*=\s*(["']?)([^"']*)\2$
正则各部分解释:
^([A-Z_]+):捕获键名,只匹配大写字母和下划线,符合locale变量的命名规则\s*=\s*:匹配等号,前后允许任意数量的空格(包括零个)(["']?):捕获可选的引号(单或双),用分组2保存,确保后续能匹配闭合的引号([^"']*):捕获变量值,匹配除引号外的所有字符(locale值本身不会包含引号)\2:引用分组2的引号,保证开头和结尾的引号一致(如果有的话)$:匹配行尾,确保整行都是有效的赋值语句
方法1:命令行快速处理(awk)
如果只是想在终端快速提取,awk是最方便的工具,它可以直接分割行并处理空格和引号:
awk -F '=' '/^[A-Z_]+=/ { # 清理键名的前后空格 key = $1; gsub(/^\s+|\s+$/, "", key) # 清理值的前后空格和引号 value = $2; gsub(/^\s*["']?|["']?\s*$/, "", value) print "键名: " key ", 值: " value }' /etc/locale.conf
运行这个命令后,会直接输出每行有效赋值的键名和对应值,自动跳过注释和空行。
方法2:grep + sed组合处理
如果你更习惯用grep筛选行,再用sed提取内容,可以这样写:
# 先用grep匹配符合格式的行,再用sed提取键值 grep -E '^[A-Z_]+\s*=\s*(["']?[^"']*\1)$' /etc/locale.conf | sed -E 's/^([A-Z_]+)\s*=\s*(["']?)([^"']*)\2$/键名: \1, 值: \3/'
这个组合同样能精准提取,适合已经熟悉grep/sed的用户。
方法3:Python脚本实现(适合扩展)
如果需要在代码里集成这个逻辑,或者要处理更复杂的场景(比如批量修改、导出到其他格式),用Python写个脚本会更灵活:
import re import os # 目标配置文件路径 locale_file = '/etc/locale.conf' # 匹配正则 pattern = r'^([A-Z_]+)\s*=\s*(["']?)([^"']*)\2$' if os.path.exists(locale_file): with open(locale_file, 'r') as f: for line in f: line = line.strip() # 跳过空行和注释行 if not line or line.startswith('#'): continue match_result = re.match(pattern, line) if match_result: key = match_result.group(1) value = match_result.group(3) print(f"键名: {key}, 值: {value}")
这个脚本会自动跳过注释和空行,输出结果清晰,还能很容易扩展成导出为JSON、修改值等功能。
注意事项
- 以上方案都默认忽略以
#开头的注释行,这符合/etc/locale.conf的常规使用场景 - 如果你的配置文件里有值包含引号的特殊情况(虽然locale配置几乎不会出现),需要调整正则的匹配逻辑
- 所有方法都支持CentOS 7/8/9等主流版本的/etc/locale.conf格式
内容的提问来源于stack exchange,提问作者user1765418
相关产品推荐
相关产品推荐

