【问题标题】:jq how to retain the parent square bracket while extracting and modifying content in jsonjq如何在提取和修改json中的内容时保留父方括号
【发布时间】:2021-06-13 15:02:25
【问题描述】:

我有下面的 JSON,我需要修改一些元素值,并且只提取 containerDefinitions 中的内容,同时保留方括号。

以下脚本用于替换所需的值并在 containerDefinitions 内的方括号内提取 json,但省略了方括号。是否有可以保留方括号的附加命令。

echo $TASK_DEFINITION | jq '.taskDefinition.containerDefinitions[0] | ( .environment[] |= if   .name == "SMT_PORT_3306_TCP_ADDR" then .value = "myvalue" elif .name == "SERVER_API_TIMEOUT_SUBSCRIPTIONS_CANCEL_REQUEST" then .value = "myvalue" else . end) | .logConfiguration.options."awslogs-group" = "myvalue" ' > ${TASK_DEFINITION_PATH}/${SERVICE_NAME}2-task-definition.json

输入 JSON

{
   "taskDefinition":{
      "taskDefinitionArn":"some value",
      "containerDefinitions":[
         {
            "name":"common-api-img",
            "environment":[
               {
                  "name":"SERVER_API_TIMEOUT_SUBSCRIPTIONS_CANCEL_REQUEST",
                  "value":"false"
               },
               {
                  "name":"SMT_PORT_3306_TCP_ADDR",
                  "value":"valueToReplace"
               }
            ],
            "mountPoints":[
               
            ],
            "volumesFrom":[
               
            ]
         }
      ],
      "revision":65,
      "volumes":[
         
      ],
      "status":"ACTIVE"
   }
}

预期输出

[
   {
      "name":"common-api-img",
      "environment":[
         {
            "name":"SERVER_API_TIMEOUT_SUBSCRIPTIONS_CANCEL_REQUEST",
            "value":"myvalue"
         },
         {
            "name":"SMT_PORT_3306_TCP_ADDR",
            "value":"myvalue"
         }
      ],
      "mountPoints":[
         
      ],
      "volumesFrom":[
         
      ]
   }
]

【问题讨论】:

  • 包含您的实际输出会很有帮助,而不仅仅是预期输出,因此只需阅读问题即可比较它们。
  • 顺便说一句,如果echo $TASK_DEFINITION 没有更改为echo "$TASK_DEFINITION" 带引号,你会得到I just assigned a variable, but echo $variable shows something else!中描述的错误
  • (您可能还希望避免为自己的变量使用全大写名称——这些名称由 POSIX 定义,用于对 shell 和 OS 本身有意义的变量,而保证符合 POSIX 的工具不要通过更新名称中至少包含一个小写字符的变量来修改其行为;请阅读pubs.opengroup.org/onlinepubs/9699919799/basedefs/…,记住修改常规 shell 变量会覆盖任何具有相同名称的环境变量。
  • (以上就是为什么在 bash 中写 for path in ... 是安全的,但写 for PATH in ... 是安全的——只有全大写变量对 shell 行为有副作用)。

标签: json bash jq


【解决方案1】:

当您将[0] 放入查询中时,您将丢弃除第一个列表条目之外的所有内容。因此,您不再有列表。因此,没有更多的方括号。

如果您想处理 所有 个项目,而不仅仅是第一个项目(从而生成项目流),并且想将该流放入列表中,您可能希望:

jq '
  .taskDefinition.containerDefinitions | map(
    ( .environment[] |=
      if .name == "SMT_PORT_3306_TCP_ADDR" then
        .value = "myvalue"
      elif .name == "SERVER_API_TIMEOUT_SUBSCRIPTIONS_CANCEL_REQUEST" then
        .value = "myvalue"
      else . end
    ) |
    .logConfiguration.options."awslogs-group" = "myvalue"
  )
'  <<<"$TASK_DEFINITIONS" >"${TASK_DEFINITION_PATH}/${SERVICE_NAME}2-task-definition.json"

注意删除[0],并使用map() 将所有列表元素传递给转换函数。


另一种方法是使用jq -n,并将inputs 放入列表中:

jq -n '
  [ inputs |
    .taskDefinition.containerDefinitions[] |
    ( .environment[] |=
      if .name == "SMT_PORT_3306_TCP_ADDR" then
        .value = "myvalue"
      elif .name == "SERVER_API_TIMEOUT_SUBSCRIPTIONS_CANCEL_REQUEST" then
        .value = "myvalue"
      else . end
    ) |
    .logConfiguration.options."awslogs-group" = "myvalue"
  ]
'  <<<"$TASK_DEFINITIONS" >"${TASK_DEFINITION_PATH}/${SERVICE_NAME}2-task-definition.json"

注意添加外部[]s,在该块内使用inputs,使用jq-n 参数,以及使用[] where @987654334 @以前用过。

【讨论】:

    【解决方案2】:

    您的 jq 程序添加 .logConfiguration 而“预期输出”没有,但除了该键之外,您的 jq 程序的以下变体保留了 [0] 并产生“预期输出”:

    [.taskDefinition.containerDefinitions[0]
     | ( .environment[] |= if .name | IN("SMT_PORT_3306_TCP_ADDR", "SERVER_API_TIMEOUT_SUBSCRIPTIONS_CANCEL_REQUEST")
                           then .value = "myvalue" else . end)
     | .logConfiguration.options."awslogs-group" = "myvalue"
    ]
    
    

    评论:

    1. 注意IN/1 的使用如何使解决方案更加干燥。

    2. 如果您的 jq 没有 IN/1,那么现在是升级的好时机,但另一种方法是简单地包含其 def,如下所示。

    3. 如果您选择避免使用[0] 的解决方案(例如支持map),您仍然可以使用IN 来避免冗余。


    def IN(s): first((s == .) // empty) // false;
    

    【讨论】:

      猜你喜欢
      • 2016-03-28
      • 1970-01-01
      • 2023-01-16
      • 2019-10-04
      • 2021-11-26
      • 2020-03-17
      • 1970-01-01
      • 2015-11-11
      • 1970-01-01
      相关资源
      最近更新 更多