I have the following JSON object:
{
"attacks": {
"normal fist": {
"type": "melee",
"damage": 3
},
"thunder fist": {
"type": "melee",
"damage": 5,
"attributes": [ "electrical" ]
}
}
}
Using jq
, I want to print the following to standard output:
attacks:
- name: normal fist
type: melee
damage: 3
- name: thunder fist
damage: 5
attributes:
electrical
This short script does most of what I want:
jq -r '.attacks | to_entries | .[] |
{
"- name":.key,
" type":.value.Type,
" damage":.value.Number,
}' | awk -F: '/ "/ { gsub(/^ /,""); gsub(/"/,""); print $0 }'
There are two problems I am facing.
#1 - I only want the "attributes" key to be printed under the "thunder fist" entry. I can't figure out how to make the printing of that portion conditional.
#2 - I can't figure out how to format the nested object "attributes."
I can't find much in the jq
documentation on formatting output. I'm trying to treat jq
as a JSON-specific awk
-- is this even possible?
CodePudding user response:
jq is Turing-complete, so if your format is well-defined, it would be possible to use jq to perform the transformation. But rather than inventing a new format, why not consider YAML:
$ gojq --yaml-output . attacks.json
attacks:
normal fist:
damage: 3
type: melee
thunder fist:
attributes:
- electrical
damage: 5
type: melee
If you really need the "-name:" prefix as shown, you could perhaps post-process the above, e.g.:
$ gojq --yaml-output . attacks.json | sed '/^ [^ ].*:$/ {s/ / - name: /; s/:$//;}'
attacks:
- name: normal fist
damage: 3
type: melee
- name: thunder fist
attributes:
- electrical
damage: 5
type: melee
CodePudding user response:
The following does the job in this particular case, but might need fortifying for more genericity:
def indentArray(indent):
(indent * " ") as $i
| .[] | "\($i)\(.)";
def simplekv(indent):
(indent * " ") as $i
| keys_unsorted[] as $k
| if .[$k] | type == "array"
then "\($i)\($k):", (.[$k] | indentArray(indent 2))
else "\($i)\($k): \(.[$k])"
end;
keys_unsorted[] as $k
| ($k ":"),
(.[$k] as $o
| ($o|keys_unsorted[]) as $k1
| ("-name: " $k1), ($o[$k1] | simplekv(2)) )