sed替换引号内字符串时出现\1无效引用报错如何解决?
问题诱因
- sed默认使用*基础正则表达式(BRE)*语法,BRE规则中捕获组的括号必须加反斜杠转义(格式为
\(捕获内容\))才会生效。你代码中直接使用普通括号,只会被识别为普通文本字符,没有创建捕获组,所以替换部分引用\1、\2时会抛出无效引用的报错。 - 原有正则逻辑存在缺陷,没有匹配两个双引号中间的旧日期内容,即使解决转义问题也无法完成替换。
- 另外你
date命令里的连字符不需要加反斜杠转义,属于多余写法。
解决方法
方案1:使用默认BRE模式(兼容性更好)
修正括号转义,同时调整正则匹配逻辑,匹配双引号内的旧日期内容:
text_date="$(date +%Y-%m-%d)" # 绝大多数Linux发行版(GNU sed环境)适用 sed -i 's/\(date = "\)[^"]*\(")/\1'"$text_date"'\2/g' "$post_dir"/index.md # macOS 环境适用 sed -i '' 's/\(date = "\)[^"]*\(")/\1'"$text_date"'\2/g' "$post_dir"/index.md
方案2:开启扩展正则模式(写法更简洁)
给sed加-E参数开启扩展正则表达式(ERE)模式,该模式下捕获组括号不需要转义:
text_date="$(date +%Y-%m-%d)" # GNU sed环境适用 sed -E -i 's/(date = ")[^"]*(")/\1'"$text_date"'\2/g' "$post_dir"/index.md # macOS环境适用 sed -E -i '' 's/(date = ")[^"]*(")/\1'"$text_date"'\2/g' "$post_dir"/index.md
优化建议
如果担心误替换文件中其他位置的相似内容,可以限定只有匹配date = 开头的行才执行替换,写法如下(以GNU sed+BRE为例):
sed -i '/^date = /s/\(date = "\)[^"]*\(")/\1'"$text_date"'\2/' "$post_dir"/index.md
内容的提问来源于stack exchange,提问作者dot rose
相关产品推荐
相关产品推荐

