I have this json string:
json_string="{\"emailRecipients\":\"['test@example.com', 'tes2t@example.com', 'test3@example.com']\", \"anotherEmails\":\"{'test1': 'test1@example.com', 'test2': 'test2@example.com', 'test3': 'test3@example.com'}\", \"some_key\": 3, \"another_key\": \"some_value\"}"
I’m trying to use jq to parse the emailRecipients as a json array and anotherEmails as a json object.
I’m trying to make a command that can work with any key, not emailRecipients just and anotherEmails. I also need to keep keys-values that don’t have json objects/arrays inside intact.
So I tried to do this:
parsed_json=$(echo "$json_string" | jq 'with_entries(
.value |= if startswith("\"[") and endswith("\"]") then
gsub("''";"\"") | fromjson
else
.
end
)')
But I don’t know why the gsub isn’t working. Any idea of what I’m doing wrong ?
>Solution :
You seem to be confusing syntax with values. The quotes are not part of the value; the value starts and ends with [ and ], respectively (not "[ and "]; the latter doesn’t even make sense if the syntax quote was part of the value). To detect objects, you need to check for { and } prefix and suffix. You need to filter for string values, otherwise you cannot apply the startswith filter.
Full program:
map_values(
if type == "string" and (startswith("[") and endswith("]") or startswith("{") and endswith("}")) then
gsub("'"; "\"") | fromjson
else
.
end
)
When used in a shell context:
parsed_json=$(printf '%s\n' "$json_string" | jq 'map_values(
if type == "string" and (startswith("[") and endswith("]") or startswith("{") and endswith("}")) then
gsub("'\''"; "\"") | fromjson
else
.
end
)')
or
parsed_json=$(printf '%s\n' "$json_string" | jq "map_values(
if type == \"string\" and (startswith(\"[\") and endswith(\"]\") or startswith(\"{\") and endswith(\"}\")) then
gsub(\"'\"; \"\\\"\") | fromjson
else
.
end
)")