如何在bash脚本中通过sed实现指定多行模式匹配替换为},字符
Elasticsearch 多DSL合并多行替换方案
问题原因
你之前的sed方案未生效,是因为sed默认工作在逐行读取模式,模式空间每次仅加载单行内容,无法直接匹配跨多行的字符串,同时你写的正则卡死了固定空格数量,遇到缩进差异就会匹配失败。
可用实现方案
方案1:Perl实现(兼容性最高,全平台通用)
Perl支持一次性读取全量内容做正则匹配,适配不同缩进/空行的场景,容错性最高:
# 全量替换所有匹配的DSL分隔片段 combinedDSL=$(printf '%s' "$initialDSLs" | perl -0777 -pe 's/}\s*\n\s*]\s*\n\s*}\s*\n\s*}\s*\n\s*}\s*\n+\s*{\s*\n\s*"query":\s*{\s*\n\s*"bool":\s*{\s*\n\s*"minimum_should_match":\s*1,\s*\n\s*"should":\s*\[\n/},/g') # 输出结果验证 echo "$combinedDSL"
方案2:GNU Sed实现(适用于Linux环境)
如果仅在Linux环境使用,可以用GNU sed的-z参数把全量输入作为单行处理:
combinedDSL=$(printf '%s' "$initialDSLs" | sed -z 's/}\s*\n\s*]\s*\n\s*}\s*\n\s*}\s*\n\s*}\s*\n\+\s*{\s*\n\s*"query":\s*{\s*\n\s*"bool":\s*{\s*\n\s*"minimum_should_match":\s*1,\s*\n\s*"should":\s*\[\n/},/g')
macOS环境需要先安装gnu-sed,将命令中的sed替换为gsed即可使用。
合并后效果示例
你提供的原始DSL执行替换后会得到如下合并结果:
{ "query": { "bool": { "minimum_should_match": 1, "should": [ { "wildcard": { "author_place": "*city*" } }, { "wildcard": { "meta.title.results": "*state*" } }, { "wildcard": { "author": "*cat*" } }, { "wildcard": { "meta.hashtag.results": "*Monkey*" } } ] } } }
内容的提问来源于stack exchange,提问作者stackmacstacky
相关产品推荐
相关产品推荐

