JSON: 使用 jq 编辑嵌套数组中的特定值

JSON: use jq to edit specific values in nested arrays

我正在尝试使用实用程序 jq 更新数组中数组中的值。我在下面粘贴了示例 json。

更具体地说:在 sheets 数组中,然后在 formulas 数组中,我想将值为 "MONTH" 的每个 columnName 更改为 "YEAR"。我想在 sheets 数组中做同样的事情,在 columnStyles 数组中,将 "MONTH" 的每个发生率也更改为 "YEAR"

这个 jq 过滤器让我得到列名列表。

.sheets[1] | .formulas[] | .columnName

如何通过更新我想要的值来就地编辑整个文件?我是否将 map 与 if 一起使用?

如果我想编辑值的一部分怎么办?例如,在 forumlaString 属性 中,仅更改字符串中包含 MONTH 的部分,但保留其余部分不变?

{
  "version": "6.1.1",
  "className": "xyz",
  "sheets": [    
  {
      "name": "Pass1",
      "sheetId": "95e6c2cd-abbe-46c1-8012-bdf37438b9b7",
      "keep": true,
      "formulas": [
        {
          "columnName": "SAMPLE_PROVIDER",
          "columnId": "0",
          "columnIndex": 0,
          "formulaString": "\u003dGROUPBY(#Raw!SAMPLE_PROVIDER)"
        },
        {
          "columnName": "MONTH",
          "columnId": "1",
          "columnIndex": 1,
          "formulaString": "\u003dGROUPBY(#Raw!MONTH)"
        }
      ],
      "columnStyles": [
        {
          "columnId": "0",
          "name": "SAMPLE_PROVIDER",
          "width": 206,
          "thousandSeparator": true
        },
        {
          "columnId": "1",
          "name": "MONTH",
          "width": 100,
          "thousandSeparator": true
        }
        ],
      "nextColumnId": 2
    },
    {
      "name": "Transform1",
      "sheetId": "49071c1c-fa84-4ae3-92c1-b63175a6b26c",
      "keep": true,
      "formulas": [
        {
          "columnName": "SAMPLE_PROVIDER",
          "columnId": "0",
          "columnIndex": 0,
          "formulaString": "\u003d#Pass1!SAMPLE_PROVIDER"
        },
        {
          "columnName": "MONTH",
          "columnId": "1",
          "columnIndex": 1,
          "formulaString": "\u003d#Pass1!MONTH"
        }
      ],
      "columnStyles": [
        {
          "columnId": "0",
          "name": "SAMPLE_PROVIDER",
          "width": 179,
          "thousandSeparator": true
        },
        {
          "columnId": "1",
          "name": "MONTH",
          "width": 100,
          "thousandSeparator": true
        }
      ],
      "nextColumnId": 3
    }
  ],
  "advancedSchedulingInUse": true,
  "errorHandlingMode": "IGNORE"
}

要更改所需容器中的 columnName 字段,您可以使用

jq '(.sheets[] | .formulas[]? | .columnName | select(.=="MONTH")) |= "YEAR"' tmp.json

? 避免在没有键 formula 时出错。)

要将公式字符串中的 MONTH 替换为 YEAR,请将每个 formulaString 值替换为 sub.

返回的可能修改后的字符串
jq '(.sheets[] | .formulas[]? | .formulaString) |= sub("MONTH"; "YEAR")' tmp.json

(sub 需要 jq 1.5,使用 Oniguruma 库编译。)

要将这些组合成一个 jq 过滤器?我不肯定;我对其中任何一个单独起作用的原因只有微弱的理解。

看来您不仅要更新公式数组中的字段,还要更新所有内容。

如果您想不加区别地将所有出现的字符串 "MONTH" 更改为 "YEAR",您可以这样做:

(.. | strings) |= sub("MONTH"; "YEAR")

这可能是 walk/1 的任务。

(如果你的jq没有walk/1,那么你可以从https://github.com/stedolan/jq/blob/master/src/builtin.jq复制它的定义)

例如,如果您想将 "MONTH" 更改为 "YEAR" 每当 "MONTH" 作为对象中的键的值出现时,则可以执行以下操作:

jq 'walk(if type == "object" then with_entries(.value |= (if . == "MONTH" then "YEAR" else . end)) else . end)' input.json

等价于: jq 'walk(if type == "object" then with_entries(if .value == "MONTH" then .value = "YEAR" else . end) else . end)' input.json

这些可以很容易地根据类似的要求进行修改。