如何在Unix中去除键值对值的引号并替换冒号空格为等号?
键值对格式转换解决方案
问题场景
有一个file.txt文件,内容为以: (冒号加空格)分隔的键值对,值可能包含单引号或双引号,且值内部可能存在: 组合。需要完成两个转换:
- 将键与值之间的
:替换为= - 移除值两端的单引号或双引号
原始文件内容
key1: "Subject %D: %W warning(s), %V Violation(s)" key2: 'sample: value' key3: "value3" key4: 'value4'
期望输出
key1=Subject %D: %W warning(s), %V Violation(s) key2=sample: value key3=value3 key4=value4
之前尝试的问题
- awk命令:用
-F': '拆分时,会误将值内部的:当作分隔符,导致值被拆分后错误替换:
awk -F': ' '{ gsub(/^'\''|'\''$/, "", $2); gsub(/^'\"'|'\"'$/, "", $2); print }' OFS='='
错误输出:
key1=Subject %D=%W warning(s), %V Violation(s)" key2=sample=value' key3=value3 key4=value4
- sed命令:同样会匹配值内部的
:进行替换,导致值被错误修改:
sed -i -e "s/: '/=/" -e "s/'$//" -e 's/: \"/=/' -e 's/\"$//' -e "s/: /=/" file.txt
错误输出:
key1=Subject %D=%W warning(s), %V Violation(s) key2=sample=value key3=value3 key4=value4
可行方案
方案1:awk精准捕获匹配
利用awk的match函数精准识别键、引号和值内容,避免误匹配值内部的: :
awk 'match($0, /^([^:]+): (["'\']?)(.*)\2$/, arr) {print arr[1] "=" arr[3]}' file.txt
说明:
- 正则
/^([^:]+): (["'\']?)(.*)\2$/匹配整行,捕获三个分组:([^:]+):键部分,匹配第一个冒号前的所有字符(["'\']?):可选的开头引号(单/双)(.*):值内容,直到与开头引号对应的结束引号
- 最终输出
键=值格式,自动移除值两端的引号
方案2:sed正则替换
通过正则仅替换第一个: ,并分别处理带引号和不带引号的情况:
sed -E 's/^([^:]+): (["'\'])(.*)\2/\1=\3/; s/^([^:]+): ([^"\'].*)$/\1=\2/' file.txt
说明:
- 第一个规则:处理带引号的键值对,将
键: "值"或键: '值'替换为键=值 - 第二个规则:处理不带引号的键值对,直接将
键: 值替换为键=值
内容的提问来源于stack exchange,提问作者user29211006
相关产品推荐
相关产品推荐

