更新字段时已知 jq 错误的解决方法
workaround for known jq error while updating fields
如果可能,我想将整个 json 中“字符串”类型的每个值更新为一个数字。
如果该值不能解析为数字,则应保留字符串。
我尝试使用 jq 解决此问题时遇到了 1.6 版的已知错误。
我不知道如何解决这个错误。
关于如何在没有 运行 这个已知错误的情况下解决任务的想法?
另请参阅:
示例输入
{
"outer": {
"inner": [
{
"foo": "foo",
"bar": "11",
"count": 12,
"data": ["13", "14"]
},
{
"foo": "foo",
"bar": "15",
"count": 16,
"child": {
"otherData": ["17", "18"]
}
}
]
}
}
期望的输出
{
"outer": {
"inner": [
{
"foo": "foo",
"bar": 11,
"count": 12,
"data": [13, 14]
},
{
"foo": "foo",
"bar": 15,
"count": 16,
"child": {
"otherData": [17, 18]
}
}
]
}
}
尝试 1 解决 - 无效
jq '(..| strings) |= try tonumber catch .'
输出
{
"outer": {
"inner": [
{
"foo": "Invalid literal at EOF at line 1, column 3 (while parsing 'foo')",
"bar": {
"__jq": 1
},
"count": 12,
"data": [
{
"__jq": 2
},
{
"__jq": 3
}
]
},
{
"foo": "Invalid literal at EOF at line 1, column 3 (while parsing 'foo')",
"bar": {
"__jq": 5
},
"count": 16,
"child": {
"otherData": [
{
"__jq": 6
},
{
"__jq": 7
}
]
}
}
]
}
}
尝试 2 来解决 - 更糟
jq '(..| strings) |= tonumber? // .'
输出
{
"outer": {
"inner": [
{
"count": 12,
"data": [
"14"
]
},
{
"count": 16,
"child": {
"otherData": [
"18"
]
}
}
]
}
}
按预期工作 - 但没有解决任务
该错误与结合 try catch 表达式的更新运算符有关
jq '(..| strings) |= (. + "___needs_update")'
{
"outer": {
"inner": [
{
"foo": "foo___needs_update",
"bar": "11___needs_update",
"count": 12,
"data": [
"13___needs_update",
"14___needs_update"
]
},
{
"foo": "foo___needs_update",
"bar": "15___needs_update",
"count": 16,
"child": {
"otherData": [
"17___needs_update",
"18___needs_update"
]
}
}
]
}
}
walk
救援:
walk(if type == "string"
then . as $in | try tonumber catch $in
else . end)
或者只是:
walk(if type == "string" then tonumber? // . else . end)
增强walk
如果您的 jq 没有 walk
,或者您想要相对于(当前)内置版本的增强版本,请参阅 jq FAQ(搜索 def walk
).
这是 jq 1.5 或更高版本的无行走解决方案:
reduce paths(strings) as $p (.;
getpath($p) as $x | setpath($p; $x | tonumber? // $x))
如果可能,我想将整个 json 中“字符串”类型的每个值更新为一个数字。 如果该值不能解析为数字,则应保留字符串。
我尝试使用 jq 解决此问题时遇到了 1.6 版的已知错误。
我不知道如何解决这个错误。 关于如何在没有 运行 这个已知错误的情况下解决任务的想法?
另请参阅:
示例输入
{
"outer": {
"inner": [
{
"foo": "foo",
"bar": "11",
"count": 12,
"data": ["13", "14"]
},
{
"foo": "foo",
"bar": "15",
"count": 16,
"child": {
"otherData": ["17", "18"]
}
}
]
}
}
期望的输出
{
"outer": {
"inner": [
{
"foo": "foo",
"bar": 11,
"count": 12,
"data": [13, 14]
},
{
"foo": "foo",
"bar": 15,
"count": 16,
"child": {
"otherData": [17, 18]
}
}
]
}
}
尝试 1 解决 - 无效
jq '(..| strings) |= try tonumber catch .'
输出
{
"outer": {
"inner": [
{
"foo": "Invalid literal at EOF at line 1, column 3 (while parsing 'foo')",
"bar": {
"__jq": 1
},
"count": 12,
"data": [
{
"__jq": 2
},
{
"__jq": 3
}
]
},
{
"foo": "Invalid literal at EOF at line 1, column 3 (while parsing 'foo')",
"bar": {
"__jq": 5
},
"count": 16,
"child": {
"otherData": [
{
"__jq": 6
},
{
"__jq": 7
}
]
}
}
]
}
}
尝试 2 来解决 - 更糟
jq '(..| strings) |= tonumber? // .'
输出
{
"outer": {
"inner": [
{
"count": 12,
"data": [
"14"
]
},
{
"count": 16,
"child": {
"otherData": [
"18"
]
}
}
]
}
}
按预期工作 - 但没有解决任务
该错误与结合 try catch 表达式的更新运算符有关
jq '(..| strings) |= (. + "___needs_update")'
{
"outer": {
"inner": [
{
"foo": "foo___needs_update",
"bar": "11___needs_update",
"count": 12,
"data": [
"13___needs_update",
"14___needs_update"
]
},
{
"foo": "foo___needs_update",
"bar": "15___needs_update",
"count": 16,
"child": {
"otherData": [
"17___needs_update",
"18___needs_update"
]
}
}
]
}
}
walk
救援:
walk(if type == "string"
then . as $in | try tonumber catch $in
else . end)
或者只是:
walk(if type == "string" then tonumber? // . else . end)
增强walk
如果您的 jq 没有 walk
,或者您想要相对于(当前)内置版本的增强版本,请参阅 jq FAQ(搜索 def walk
).
这是 jq 1.5 或更高版本的无行走解决方案:
reduce paths(strings) as $p (.;
getpath($p) as $x | setpath($p; $x | tonumber? // $x))