如何在Terraform文件中跨空白使用Bash-RegexLookbacking



我正在编写一个bash脚本来解析一堆(十几个或更多(巨大的Terraform文件,这些文件包含大量的google_bigquery_dataset资源及其关联的IAM访问块。脚本应该获取每个数据集资源,并将其复制到另一个以数据集本身命名的文件中。

所有这些都很好,除了从资源的";dataset_id";领域如果不是因为这些数据集资源中的一些已经授权的视图块也包含";dataset_id";价值观

下面是这样一个资源的例子:

resource "google_bigquery_dataset" "project-bigquery-dataset-RESOURCE_NAME" {
access {
role          = "WRITER"
special_group = "projectWriters"
}
access {
role          = "READER"
special_group = "projectReaders"
}
access {
role          = "WRITER"
user_by_email = "user1@project.iam.gserviceaccount.com"
}
access {
role          = "OWNER"
special_group = "projectOwners"
}
access {
view {
dataset_id = "DO_NOT_WANT"
project_id = "project"
table_id   = "table1"
}
}
access {
view {
dataset_id = "DO_NOT_WANT"
project_id = "project"
table_id   = "table2"
}
}
access {
view {
dataset_id = "DO_NOT_WANT"
project_id = "project"
table_id   = "table3"
}
}
dataset_id                      = "THIS_IS_WHAT_I_WANT"
default_partition_expiration_ms = "0"
delete_contents_on_destroy      = "false"
labels = {
application-name = "app-name"
}
location = "US"
project  = "project"
}

在我意识到授权的视图块也有一个dataset_id字段之前,我正在使用它来尝试获取我想要的值,假设startIndexendIndex只是表示完整数据集资源块的开始和结束行号,如上所述:

fileName=$( sed -n ${startIndex},${endIndex}p $bigFile | grep "dataset_id" | cut -d" -f2)

只有在没有包含其他dataset_id值的"授权视图"块的情况下才有效。

然后我试着使用负向后看:

fileName=$( sed -n ${startIndex},${endIndex}p $bigFile | grep '(?<!view {]n)dataset_id' | cut -f1 -d"

这行不通。我不确定是因为换行还是因为view {结尾和dataset_id = "DO_NOT_WANT"开头之间的空白。

我尝试过它的变体,比如(?<!views{s)s*dataset_id,但没有成功。

有没有办法只捕获不在视图块中的dataset_id

注意事项:

  1. 我可以保证view {总是在块中的dataset_id之前,没有换行
  2. 我不能保证订单。我试图捕捉的dataset_id可能出现在view块之前、之后,甚至介于它们之间
  3. 上述示例的期望输出将简单地为THIS_IS_WHAT_I_WANT如有任何帮助,我们将不胜感激

只显示示例,请尝试以下awk代码。用GNUawk编写和测试。

awk -v RS= -v FS="n" '
/^[[:space:]]+dataset_id[[:space:]]+/{
split($1,arr,""")
print arr[2]
}
'  Input_file

解释:完整代码的简单解释是:

  • awk程序中将RS(记录分隔符(设置为段落模式
  • 然后将FS(字段分隔符(设置为新行
  • 然后在主块检查条件下,如果行从1个或多个空格开始,然后是dataset_id,然后是1个或更多空格,如果此条件为TRUE,则:
  • 使用awksplit函数将$1(第一个字段(拆分为一个名为arr的数组,分隔符为"。这基本上创建了一个名为arr的数组,其索引为1 2 3 4,依此类推,具体取决于它根据分隔符拆分的元素数量
  • 然后打印阵列arr的第二个元素,这是OP需要输出的

如果您的grep支持-P(PCRE(选项,请尝试以下操作。它是用你展示的样品测试的。

grep -Poz '(?:^|n)(?:(?!view).)*ns*dataset_ids*=s*"K[^"]+' input_file

输出:

THIS_IS_WHAT_I_WANT

假设

  • 如果view {先于dataset_id,则两个单词的跨度连续两行

解释

  • 由于我们需要检查跨行的模式匹配,因此放置了-z选项到CCD_ 31以将输入视为行序列
  • 正则表达式(?:^|n)(?:(?!view).)*ns*dataset_ids*=s*"K[^"]+匹配(至少(不包含单词view的两行在包含CCD_ 34的行之前的前一行中
  • (?:^|n)将线的起点固定为多行选项由于-z选项,(?m)不起作用
  • 由于lookbehind断言不允许可变长度匹配,我们需要使用CCD_ 39作为CCD_
  • 以下ns*dataset_id确保至少有一个换行符存在于CCD_ 42和CCD_。否则,正则表达式与仅包含CCD_ 44的单线引起过检测
  • K丢弃先前匹配的子串以将其排除在输出中

不能保证使用hcl,但可以尝试先转换为json

$ cat foo.tf | 
yj -c | 
jq  -r '.resource[].google_bigquery_dataset[][][].dataset_id'
THIS_IS_WHAT_I_WANT
THIS_IS_WHAT_I_WANT

相关内容

  • 没有找到相关文章

最新更新