You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Bash正则反向匹配提取Terraform文件中非view块的dataset_id

解决Terraform中提取google_bigquery_dataset顶层dataset_id的问题

问题分析

你需要从Terraform的google_bigquery_dataset资源块中提取顶层的dataset_id,但资源内的access.view块中也包含同名字段,导致普通文本匹配方法失效。核心需求是仅捕获不在view块内的dataset_id。

解决方案:用AWK跟踪块状态提取

由于view块和内部的dataset_id是跨行结构,逐行匹配的grep无法有效区分上下文,推荐用AWK跟踪当前是否处于view块内,精准提取目标字段:

fileName=$(sed -n "${startIndex},${endIndex}p" "$bigFile" | awk '
  # 进入view块时标记状态
  /view {/ { in_view = 1 }
  # 退出view块时取消标记(仅当当前在view块内时)
  /}/ { if (in_view) in_view = 0 }
  # 匹配不在view块内的dataset_id行,提取引号内的值
  /dataset_id/ && !in_view {
    # 移除行首到dataset_id引号前的所有内容
    sub(/.*dataset_id[[:space:]]*=[[:space:]]*"/, "", $0)
    # 移除引号及后面的所有内容
    sub(/".*/, "", $0)
    print $0
    exit  # 每个资源仅一个顶层dataset_id,找到后直接退出
  }
')

脚本逻辑说明

  1. 状态跟踪:通过in_view变量标记当前是否处于view块内部,遇到view {时开启标记,遇到}且处于view块内时关闭标记。
  2. 精准匹配:仅处理包含dataset_id且不在view块内的行。
  3. 值提取:通过两次sub操作剥离字段名和引号,直接提取目标字符串。
  4. 效率优化:找到目标值后立即exit,避免多余处理。

替代方案(仅当系统支持grep -P时)

如果你的系统grep支持Perl兼容正则(如Linux的GNU grep),可以用跨行匹配的思路,但可靠性不如AWK(依赖固定格式):

fileName=$(sed -n "${startIndex},${endIndex}p" "$bigFile" | grep -A1 -B100 "dataset_id" | grep -v "view {" | grep -oP '(?<=")[^"]+')

不过此方法依赖dataset_id周围的行结构,稳定性较差,优先推荐AWK方案。


内容的提问来源于stack exchange,提问作者dxh3707

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 15:01:18