I want to update each value of type "string" in an entire json to a number if possible. If the value cannot be parsed as a number, the string should be kept.
My attempt to solve this with jq runs into a known bug of version 1.6.
I can't figure out how to workaround this bug. Any ideas how to solve the task without running into this known bug?
See also: Update operator yields empty object in JQ
example input
{
"outer": {
"inner": [
{
"foo": "foo",
"bar": "11",
"count": 12,
"data": ["13", "14"]
},
{
"foo": "foo",
"bar": "15",
"count": 16,
"child": {
"otherData": ["17", "18"]
}
}
]
}
}
desired output
{
"outer": {
"inner": [
{
"foo": "foo",
"bar": 11,
"count": 12,
"data": [13, 14]
},
{
"foo": "foo",
"bar": 15,
"count": 16,
"child": {
"otherData": [17, 18]
}
}
]
}
}
attempt 1 to solve - not working
jq '(..| strings) |= try tonumber catch .'
output
{
"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
}
]
}
}
]
}
}
attempt 2 to solve - even worse
jq '(..| strings) |= tonumber? // .'
output
{
"outer": {
"inner": [
{
"count": 12,
"data": [
"14"
]
},
{
"count": 16,
"child": {
"otherData": [
"18"
]
}
}
]
}
}
working as expected - but does not solve the task
the bug is related to update operator in combination with try catch expression
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"
]
}
}
]
}
}