使用特定 属性 的值对 HCL 块进行排序

Sort a HCL block with specific property's value

我想用 env

对 HCL 块进行排序

之前

resource "datadog_monitor" "A" {
  tags = ["env:stg"]
}

resource "datadog_monitor" "B" {
  tags = ["env:dev"]
}

之后

resource "datadog_monitor" "B" {
  tags = ["env:dev"]
}

resource "datadog_monitor" "A" {
  tags = ["env:stg"]
}

嗯,这不是微不足道的。 Vim sort 有一个用于排序模式的正则表达式。

:'<,'>sort /tags = \["env:/

会告诉 vim 忽略 "env: 之前的所有内容,然后才进行排序。 但这适用于代码行而不是块。所以你的代码将被拆分。

要在 vim 中解决此问题,可以在排序前将相关行连接在一起:

:g/tags/norm JkJ

这允许之前的排序工作。 再次拆分它是微不足道的:

:%s/{/{\r/g
:%s/}/}\r/g

但最终,我想肯定有比 vim 更好的工具。也许真正了解 awk 的人可以创建更优雅的解决方案。 (并且可能还有其他 vim 解决方案)。

通常的方法是将块压缩成单行,对这些行进行排序,然后将块扩展回其原始形式。假设:缓冲区只包含那些块。

  1. 挤压

    :[range]g/^res/.,/^}/s/\n/§
    

    解释:

    • [range] 中以 res 开头的每一行(默认为 %),
    • 用奇特的字符 § 替换 EOL \n

    结果:

    resource "datadog_monitor" "A" {§  tags = ["env:stg"]§}§
    resource "datadog_monitor" "B" {§  tags = ["env:dev"]§}§
    
  2. 排序

    :[range]sort /env/
    

    解释:

    • [range] 中的行进行排序(默认为 %),
    • 基于 env.
    • 之后的内容

    结果:

    resource "datadog_monitor" "B" {§  tags = ["env:dev"]§}§
    resource "datadog_monitor" "A" {§  tags = ["env:stg"]§}§
    
  3. 解压

    :[range]g/^res/s/§/\r/g
    

    解释:

    • [range] 中以 res 开头的每一行(默认为 %),
    • 用适当的 EOL 字符替换每个花哨的字符 §

    结果:

    resource "datadog_monitor" "B" {
      tags = ["env:dev"]
    }
    
    resource "datadog_monitor" "A" {
      tags = ["env:stg"]
    }
    

参见 :help :range:help :global:help :substitute:help :sort