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
这些可以很容易地根据类似的要求进行修改。
我正在尝试使用实用程序 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
这些可以很容易地根据类似的要求进行修改。