Bash脚本中如何用正则表达式插入空格?脚本问题求助
sed脚本错误排查与修正
原脚本问题
用户提供的脚本如下:
#!/bin/bash STRING1='abcdefg' STRING2='1234567' SEDPARSE1='sed -e s/.*(bc).*(23).*/\1\t\2/g' SEDPARSE2='sed -e s/.*(bc).*(23).*/\1\s\2/g' SEDPARSE3='sed -e s/.*(bc).*(23).*/\1 \2/g' echo "${STRING1}${STRING2}" | ${SEDPARSE1} echo "${STRING1}${STRING2}" | ${SEDPARSE2} echo "${STRING1}${STRING2}" | ${SEDPARSE3}
运行时只有SEDPARSE1能执行但输出制表符分隔的结果,SEDPARSE2和SEDPARSE3均报错,期望输出bc 23(空格分隔)。
问题根源
- 正则分组括号未转义:默认sed使用基本正则表达式(BRE)语法,
()是普通字符,若要实现捕获分组,必须转义为\(和\)。原脚本未转义括号,导致sed无法识别捕获分组,匹配失败进而报错。 \s不被BRE支持:SEDPARSE2中的\s是扩展正则表达式(ERE)的元字符,BRE语法不识别,会被当作字面量s处理,进一步导致匹配失败。- 变量引用的分词问题:直接用
${SEDPARSEX}引用命令字符串时,bash会对其进行分词,可能破坏sed命令的结构,尤其是包含特殊字符时。
修正方案
方案1:使用BRE语法(转义括号)
将捕获括号转义,直接用空格分隔捕获组:
#!/bin/bash STRING1='abcdefg' STRING2='1234567' # 转义括号,用空格分隔\1和\2 SEDPARSE_FIXED='sed -e s/.*\(bc\).*\(23\).*/\1 \2/g' echo "${STRING1}${STRING2}" | ${SEDPARSE_FIXED}
方案2:使用ERE语法(加-r参数)
使用扩展正则表达式时,无需转义括号,写法更简洁:
#!/bin/bash STRING1='abcdefg' STRING2='1234567' # 加-r启用ERE,括号无需转义 SEDPARSE_FIXED='sed -r -e s/.*(bc).*(23).*/\1 \2/g' echo "${STRING1}${STRING2}" | ${SEDPARSE_FIXED}
方案3:用函数替代变量存储命令(更可靠)
避免变量引用的分词问题,用函数封装sed命令:
#!/bin/bash STRING1='abcdefg' STRING2='1234567' parse_sed() { sed -r -e 's/.*(bc).*(23).*/\1 \2/g' } echo "${STRING1}${STRING2}" | parse_sed
以上三种方案运行后均会输出bc 23,符合需求。
内容的提问来源于stack exchange,提问作者sshc
相关产品推荐
相关产品推荐

