1

如果有帮助,这在 TF V0.12 中。在一个目录中,我有可变数量的单行文件。
我需要以某种方式读取它们的内容,并将它们与换行符连接起来,并将结果存储到一个变量中。(不是字符串数组)我知道我可以使用以下方法获取要读取的文件列表:

locals{
  my files=tolist(fileset("${var.file_path}", "**")) }

如果我只有一个文件,我知道我可以使用

locals {
  file_value=file("${var.file_path}\\${local.my_files}") # if there was only a single file
}

但是我的大脑只是转向棉花,我如何才能读取多个,我觉得我应该在空资源中使用计数和连接,但似乎无法解决逻辑。这是正确的道路还是我应该怎么做?

4

3 回答 3

4

我们可以将这个问题分解为三个步骤:

  1. 枚举与所需模式匹配的文件名。
  2. 将每个文件的内容读入内存。
  3. 将所有文件内容连接在一起。

我们可以将上面的内容重新表述为三个局部值表达式,每一个都建立在前一个的基础上:

locals {
  filenames            = fileset(".", "${var.file_path}/**")
  file_contents        = { for fn in local.filenames : fn => file(fn) }
  file_contents_concat = join("\n", local.file_contents)
}

或者,我们可以在一个表达式中一起完成所有这些步骤:

locals {
  file_contents_concat = join("\n", [
    for fn in fileset(".", "${var.file_path}/**") : file(fn)
  ])
}

请注意,在fileset调用中我包含var.file_pathpattern参数中而不是path参数中,因为这样生成的文件路径都将相对于当前工作目录,因此我们可以直接将它们传递给file而无需重新添加到var.file_path那里。

path(和patternfor之间的分离fileset有助于解决将一堆文件镜像到 S3 等情况,在这种情况下,将生成的路径相对于存储桶根目录而不是当前工作目录很有帮助,但这种映射不是这里很重要,因为文件名根本不会出现在结果中。)

于 2020-02-18T19:10:37.823 回答
1

在本地与 null_resource 连接。

resource "null_resource" "concatenate_my_files" {
  provisioner "local-exec" {
    working_dir = "${var.file_path}"
    command = <<EOF
      cat "${local.my_files}" > "${var.concatenated_file_name}"
EOF
  }
}
于 2020-02-18T02:58:23.317 回答
1

谢谢@mon,它提醒我我应该永远亲吻

消除我最终得到的复杂性

resource "null_resource" "concatenate_my_files" {
  provisioner "local-exec" {
    working_dir = var.file_path
    command = <<EOF
cat * > my_temp_file
EOF
  }
}

然后我可以像以前一样阅读这个。

于 2020-02-18T10:48:57.820 回答