How to convert a json response into yaml in bash
I read data from a json file with jq. I wanna append the results into a yaml file, but I dont get it working. I am quite new to shell programming. My goal is to append that "users" to an existing "users"-Array in a yaml file.
This is my json file:
#$DEFAULTS_FILE
"users":
[
"name":"pi",
"gecos": "Hypriot Pirate",
"sudo":"ALL=(ALL) NOPASSWD:ALL",
"shell": "/bin/bash",
"groups":"users,docker,video",
"plain_text_passwd":"pi",
"lock_passwd":"false",
"ssh_pwauth":"true",
"chpasswd": "expire": false
,
"name":"admin",
"gecos": "Hypriot Pirate",
"sudo":"ALL=(ALL) NOPASSWD:ALL",
"shell": "/bin/bash",
"primary-group": "users",
"groups":"users,docker,adm,dialout,audio,plugdev,netdev,video",
"ssh-import-id":"None",
"plain_text_passwd":"pi",
"lock_passwd":"true",
"ssh_pwauth":"true",
"chpasswd": "expire: false",
"ssh-authorized-keys": ["ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local"]
]
I filter it with that:
cat $DEFAULTS_FILE | jq .users
I have no clue how to convert that json into a yaml.
My expected result should be:
users:
- name: pi
gecos: "Hypriot Pirate"
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: users,docker,video
plain_text_passwd: pi
lock_passwd: false
ssh_pwauth: true
chpasswd: expire: false
- name: admin
primary-group: users
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
groups: users,docker,adm,dialout,audio,plugdev,netdev,video
ssh-import-id: None
I tried to use a second tool called yq
which is similar to jq
and can write yaml files. But I have no positive progress.
EDIT
I know that I can add content to the yaml with that:
yq w -i "my.yml" "users[+]" "some content"
But I dont know how to merge my json into that.
Any help or hint would be nice, thank you in advance...
json bash shell yaml jq
|
show 1 more comment
I read data from a json file with jq. I wanna append the results into a yaml file, but I dont get it working. I am quite new to shell programming. My goal is to append that "users" to an existing "users"-Array in a yaml file.
This is my json file:
#$DEFAULTS_FILE
"users":
[
"name":"pi",
"gecos": "Hypriot Pirate",
"sudo":"ALL=(ALL) NOPASSWD:ALL",
"shell": "/bin/bash",
"groups":"users,docker,video",
"plain_text_passwd":"pi",
"lock_passwd":"false",
"ssh_pwauth":"true",
"chpasswd": "expire": false
,
"name":"admin",
"gecos": "Hypriot Pirate",
"sudo":"ALL=(ALL) NOPASSWD:ALL",
"shell": "/bin/bash",
"primary-group": "users",
"groups":"users,docker,adm,dialout,audio,plugdev,netdev,video",
"ssh-import-id":"None",
"plain_text_passwd":"pi",
"lock_passwd":"true",
"ssh_pwauth":"true",
"chpasswd": "expire: false",
"ssh-authorized-keys": ["ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local"]
]
I filter it with that:
cat $DEFAULTS_FILE | jq .users
I have no clue how to convert that json into a yaml.
My expected result should be:
users:
- name: pi
gecos: "Hypriot Pirate"
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: users,docker,video
plain_text_passwd: pi
lock_passwd: false
ssh_pwauth: true
chpasswd: expire: false
- name: admin
primary-group: users
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
groups: users,docker,adm,dialout,audio,plugdev,netdev,video
ssh-import-id: None
I tried to use a second tool called yq
which is similar to jq
and can write yaml files. But I have no positive progress.
EDIT
I know that I can add content to the yaml with that:
yq w -i "my.yml" "users[+]" "some content"
But I dont know how to merge my json into that.
Any help or hint would be nice, thank you in advance...
json bash shell yaml jq
1
You can usepython
/perl
which have in-builtYAML
andJSON
modules - commandlinefu.com/commands/view/12218/convert-yaml-to-json
– Inian
Nov 15 '18 at 9:11
That's exact the opposite direction
– Jan
Nov 15 '18 at 9:18
1
Bash itself is not a good platform for this. Find an existing tool, or write one in e.g. Python. Depending on your preferred language, it should not be hard to find an existing question on Stack Overflow with suggestions; here's a search for Python
– tripleee
Nov 15 '18 at 10:04
Please follow the Minimal, Complete, and Verifiable example guidelines. In particular, a sample my.yml (i.e. input) would be helpful.
– peak
Nov 15 '18 at 10:17
yq r input.json
should do the job.
– AHT
Nov 15 '18 at 18:15
|
show 1 more comment
I read data from a json file with jq. I wanna append the results into a yaml file, but I dont get it working. I am quite new to shell programming. My goal is to append that "users" to an existing "users"-Array in a yaml file.
This is my json file:
#$DEFAULTS_FILE
"users":
[
"name":"pi",
"gecos": "Hypriot Pirate",
"sudo":"ALL=(ALL) NOPASSWD:ALL",
"shell": "/bin/bash",
"groups":"users,docker,video",
"plain_text_passwd":"pi",
"lock_passwd":"false",
"ssh_pwauth":"true",
"chpasswd": "expire": false
,
"name":"admin",
"gecos": "Hypriot Pirate",
"sudo":"ALL=(ALL) NOPASSWD:ALL",
"shell": "/bin/bash",
"primary-group": "users",
"groups":"users,docker,adm,dialout,audio,plugdev,netdev,video",
"ssh-import-id":"None",
"plain_text_passwd":"pi",
"lock_passwd":"true",
"ssh_pwauth":"true",
"chpasswd": "expire: false",
"ssh-authorized-keys": ["ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local"]
]
I filter it with that:
cat $DEFAULTS_FILE | jq .users
I have no clue how to convert that json into a yaml.
My expected result should be:
users:
- name: pi
gecos: "Hypriot Pirate"
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: users,docker,video
plain_text_passwd: pi
lock_passwd: false
ssh_pwauth: true
chpasswd: expire: false
- name: admin
primary-group: users
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
groups: users,docker,adm,dialout,audio,plugdev,netdev,video
ssh-import-id: None
I tried to use a second tool called yq
which is similar to jq
and can write yaml files. But I have no positive progress.
EDIT
I know that I can add content to the yaml with that:
yq w -i "my.yml" "users[+]" "some content"
But I dont know how to merge my json into that.
Any help or hint would be nice, thank you in advance...
json bash shell yaml jq
I read data from a json file with jq. I wanna append the results into a yaml file, but I dont get it working. I am quite new to shell programming. My goal is to append that "users" to an existing "users"-Array in a yaml file.
This is my json file:
#$DEFAULTS_FILE
"users":
[
"name":"pi",
"gecos": "Hypriot Pirate",
"sudo":"ALL=(ALL) NOPASSWD:ALL",
"shell": "/bin/bash",
"groups":"users,docker,video",
"plain_text_passwd":"pi",
"lock_passwd":"false",
"ssh_pwauth":"true",
"chpasswd": "expire": false
,
"name":"admin",
"gecos": "Hypriot Pirate",
"sudo":"ALL=(ALL) NOPASSWD:ALL",
"shell": "/bin/bash",
"primary-group": "users",
"groups":"users,docker,adm,dialout,audio,plugdev,netdev,video",
"ssh-import-id":"None",
"plain_text_passwd":"pi",
"lock_passwd":"true",
"ssh_pwauth":"true",
"chpasswd": "expire: false",
"ssh-authorized-keys": ["ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local"]
]
I filter it with that:
cat $DEFAULTS_FILE | jq .users
I have no clue how to convert that json into a yaml.
My expected result should be:
users:
- name: pi
gecos: "Hypriot Pirate"
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: users,docker,video
plain_text_passwd: pi
lock_passwd: false
ssh_pwauth: true
chpasswd: expire: false
- name: admin
primary-group: users
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
groups: users,docker,adm,dialout,audio,plugdev,netdev,video
ssh-import-id: None
I tried to use a second tool called yq
which is similar to jq
and can write yaml files. But I have no positive progress.
EDIT
I know that I can add content to the yaml with that:
yq w -i "my.yml" "users[+]" "some content"
But I dont know how to merge my json into that.
Any help or hint would be nice, thank you in advance...
json bash shell yaml jq
json bash shell yaml jq
edited Nov 15 '18 at 9:17
Jan
asked Nov 15 '18 at 9:05
JanJan
2,2231944
2,2231944
1
You can usepython
/perl
which have in-builtYAML
andJSON
modules - commandlinefu.com/commands/view/12218/convert-yaml-to-json
– Inian
Nov 15 '18 at 9:11
That's exact the opposite direction
– Jan
Nov 15 '18 at 9:18
1
Bash itself is not a good platform for this. Find an existing tool, or write one in e.g. Python. Depending on your preferred language, it should not be hard to find an existing question on Stack Overflow with suggestions; here's a search for Python
– tripleee
Nov 15 '18 at 10:04
Please follow the Minimal, Complete, and Verifiable example guidelines. In particular, a sample my.yml (i.e. input) would be helpful.
– peak
Nov 15 '18 at 10:17
yq r input.json
should do the job.
– AHT
Nov 15 '18 at 18:15
|
show 1 more comment
1
You can usepython
/perl
which have in-builtYAML
andJSON
modules - commandlinefu.com/commands/view/12218/convert-yaml-to-json
– Inian
Nov 15 '18 at 9:11
That's exact the opposite direction
– Jan
Nov 15 '18 at 9:18
1
Bash itself is not a good platform for this. Find an existing tool, or write one in e.g. Python. Depending on your preferred language, it should not be hard to find an existing question on Stack Overflow with suggestions; here's a search for Python
– tripleee
Nov 15 '18 at 10:04
Please follow the Minimal, Complete, and Verifiable example guidelines. In particular, a sample my.yml (i.e. input) would be helpful.
– peak
Nov 15 '18 at 10:17
yq r input.json
should do the job.
– AHT
Nov 15 '18 at 18:15
1
1
You can use
python
/perl
which have in-built YAML
and JSON
modules - commandlinefu.com/commands/view/12218/convert-yaml-to-json– Inian
Nov 15 '18 at 9:11
You can use
python
/perl
which have in-built YAML
and JSON
modules - commandlinefu.com/commands/view/12218/convert-yaml-to-json– Inian
Nov 15 '18 at 9:11
That's exact the opposite direction
– Jan
Nov 15 '18 at 9:18
That's exact the opposite direction
– Jan
Nov 15 '18 at 9:18
1
1
Bash itself is not a good platform for this. Find an existing tool, or write one in e.g. Python. Depending on your preferred language, it should not be hard to find an existing question on Stack Overflow with suggestions; here's a search for Python
– tripleee
Nov 15 '18 at 10:04
Bash itself is not a good platform for this. Find an existing tool, or write one in e.g. Python. Depending on your preferred language, it should not be hard to find an existing question on Stack Overflow with suggestions; here's a search for Python
– tripleee
Nov 15 '18 at 10:04
Please follow the Minimal, Complete, and Verifiable example guidelines. In particular, a sample my.yml (i.e. input) would be helpful.
– peak
Nov 15 '18 at 10:17
Please follow the Minimal, Complete, and Verifiable example guidelines. In particular, a sample my.yml (i.e. input) would be helpful.
– peak
Nov 15 '18 at 10:17
yq r input.json
should do the job.– AHT
Nov 15 '18 at 18:15
yq r input.json
should do the job.– AHT
Nov 15 '18 at 18:15
|
show 1 more comment
2 Answers
2
active
oldest
votes
I'm not sure what rules you're using to get to your expected result. It seems like you're randomly applying different rules to how the values are being converted.
As I understand it, scalar values are just output as is (with potential encoding), objects are output as key/value pairs, and array objects are output with a -
for every item. The indentation associates what's part of what.
So based on those rules if you're going to use jq:
def yamlify:
(objects | to_entries | (.value | type) as $type |
if $type == "array" then
"(.key):", (.value | yamlify)
elif $type == "object" then
"(.key):", " (.value | yamlify)"
else
"(.key):t(.value)"
end
)
// (arrays | select(length > 0) | [yamlify] |
" - (.[0])", " (.[1:])"
)
// .
;
Then to use it, add it to your .jq
file and use it:
$ jq -r yamlify input.json
users:
- name: pi
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: users,docker,video
plain_text_passwd: pi
lock_passwd: false
ssh_pwauth: true
chpasswd:
expire: false
- name: admin
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
primary-group: users
groups: users,docker,adm,dialout,audio,plugdev,netdev,video
ssh-import-id: None
plain_text_passwd: pi
lock_passwd: true
ssh_pwauth: true
chpasswd: expire: false
ssh-authorized-keys:
- ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local
Here's another variation that aligns the values
def yamlify2:
(objects | to_entries | (map(.key | length) | max + 2) as $w |
. | (.value | type) as $type |
if $type == "array" then
"(.key):", (.value | yamlify2)
elif $type == "object" then
"(.key):", " (.value | yamlify2)"
else
"(.key):(" " * (.key | $w - length))(.value)"
end
)
// (arrays | select(length > 0) | [yamlify2] |
" - (.[0])", " (.[1:])"
)
// .
;
$ jq -r yamlify2 input.json
users:
- name: pi
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: users,docker,video
plain_text_passwd: pi
lock_passwd: false
ssh_pwauth: true
chpasswd:
expire: false
- name: admin
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
primary-group: users
groups: users,docker,adm,dialout,audio,plugdev,netdev,video
ssh-import-id: None
plain_text_passwd: pi
lock_passwd: true
ssh_pwauth: true
chpasswd: expire: false
ssh-authorized-keys:
- ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local
add a comment |
I ended up installing a gem and using ruby:
gem install deep_merge
(https://github.com/danielsdeleo/deep_merge)
Here is my approach:
#!/usr/bin/env ruby
#
require 'json'
require 'yaml'
require 'deep_merge/rails_compat'
json_input_file = ARGF.argv[0]
yaml_output_file = ARGF.argv[1]
scope = ARGF.argv[2]
json = File.read(json_input_file)
yaml = File.read(yaml_output_file)
json_data = JSON.parse(json)
scoped_result = json_data[scope]
old_values_hash = YAML.load(File.read(yaml_output_file))
result = YAML.parse(yaml)
merged = old_values_hash.deeper_merge scoped_result
File.write(yaml_output_file, merged.to_yaml)
It then can be used to read a specific scoped_value
from a json file.
jsonyaml.sh $JSON_FILE $YAML_TARGET "my_scope_to_add"
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53315791%2fhow-to-convert-a-json-response-into-yaml-in-bash%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
I'm not sure what rules you're using to get to your expected result. It seems like you're randomly applying different rules to how the values are being converted.
As I understand it, scalar values are just output as is (with potential encoding), objects are output as key/value pairs, and array objects are output with a -
for every item. The indentation associates what's part of what.
So based on those rules if you're going to use jq:
def yamlify:
(objects | to_entries | (.value | type) as $type |
if $type == "array" then
"(.key):", (.value | yamlify)
elif $type == "object" then
"(.key):", " (.value | yamlify)"
else
"(.key):t(.value)"
end
)
// (arrays | select(length > 0) | [yamlify] |
" - (.[0])", " (.[1:])"
)
// .
;
Then to use it, add it to your .jq
file and use it:
$ jq -r yamlify input.json
users:
- name: pi
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: users,docker,video
plain_text_passwd: pi
lock_passwd: false
ssh_pwauth: true
chpasswd:
expire: false
- name: admin
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
primary-group: users
groups: users,docker,adm,dialout,audio,plugdev,netdev,video
ssh-import-id: None
plain_text_passwd: pi
lock_passwd: true
ssh_pwauth: true
chpasswd: expire: false
ssh-authorized-keys:
- ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local
Here's another variation that aligns the values
def yamlify2:
(objects | to_entries | (map(.key | length) | max + 2) as $w |
. | (.value | type) as $type |
if $type == "array" then
"(.key):", (.value | yamlify2)
elif $type == "object" then
"(.key):", " (.value | yamlify2)"
else
"(.key):(" " * (.key | $w - length))(.value)"
end
)
// (arrays | select(length > 0) | [yamlify2] |
" - (.[0])", " (.[1:])"
)
// .
;
$ jq -r yamlify2 input.json
users:
- name: pi
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: users,docker,video
plain_text_passwd: pi
lock_passwd: false
ssh_pwauth: true
chpasswd:
expire: false
- name: admin
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
primary-group: users
groups: users,docker,adm,dialout,audio,plugdev,netdev,video
ssh-import-id: None
plain_text_passwd: pi
lock_passwd: true
ssh_pwauth: true
chpasswd: expire: false
ssh-authorized-keys:
- ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local
add a comment |
I'm not sure what rules you're using to get to your expected result. It seems like you're randomly applying different rules to how the values are being converted.
As I understand it, scalar values are just output as is (with potential encoding), objects are output as key/value pairs, and array objects are output with a -
for every item. The indentation associates what's part of what.
So based on those rules if you're going to use jq:
def yamlify:
(objects | to_entries | (.value | type) as $type |
if $type == "array" then
"(.key):", (.value | yamlify)
elif $type == "object" then
"(.key):", " (.value | yamlify)"
else
"(.key):t(.value)"
end
)
// (arrays | select(length > 0) | [yamlify] |
" - (.[0])", " (.[1:])"
)
// .
;
Then to use it, add it to your .jq
file and use it:
$ jq -r yamlify input.json
users:
- name: pi
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: users,docker,video
plain_text_passwd: pi
lock_passwd: false
ssh_pwauth: true
chpasswd:
expire: false
- name: admin
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
primary-group: users
groups: users,docker,adm,dialout,audio,plugdev,netdev,video
ssh-import-id: None
plain_text_passwd: pi
lock_passwd: true
ssh_pwauth: true
chpasswd: expire: false
ssh-authorized-keys:
- ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local
Here's another variation that aligns the values
def yamlify2:
(objects | to_entries | (map(.key | length) | max + 2) as $w |
. | (.value | type) as $type |
if $type == "array" then
"(.key):", (.value | yamlify2)
elif $type == "object" then
"(.key):", " (.value | yamlify2)"
else
"(.key):(" " * (.key | $w - length))(.value)"
end
)
// (arrays | select(length > 0) | [yamlify2] |
" - (.[0])", " (.[1:])"
)
// .
;
$ jq -r yamlify2 input.json
users:
- name: pi
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: users,docker,video
plain_text_passwd: pi
lock_passwd: false
ssh_pwauth: true
chpasswd:
expire: false
- name: admin
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
primary-group: users
groups: users,docker,adm,dialout,audio,plugdev,netdev,video
ssh-import-id: None
plain_text_passwd: pi
lock_passwd: true
ssh_pwauth: true
chpasswd: expire: false
ssh-authorized-keys:
- ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local
add a comment |
I'm not sure what rules you're using to get to your expected result. It seems like you're randomly applying different rules to how the values are being converted.
As I understand it, scalar values are just output as is (with potential encoding), objects are output as key/value pairs, and array objects are output with a -
for every item. The indentation associates what's part of what.
So based on those rules if you're going to use jq:
def yamlify:
(objects | to_entries | (.value | type) as $type |
if $type == "array" then
"(.key):", (.value | yamlify)
elif $type == "object" then
"(.key):", " (.value | yamlify)"
else
"(.key):t(.value)"
end
)
// (arrays | select(length > 0) | [yamlify] |
" - (.[0])", " (.[1:])"
)
// .
;
Then to use it, add it to your .jq
file and use it:
$ jq -r yamlify input.json
users:
- name: pi
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: users,docker,video
plain_text_passwd: pi
lock_passwd: false
ssh_pwauth: true
chpasswd:
expire: false
- name: admin
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
primary-group: users
groups: users,docker,adm,dialout,audio,plugdev,netdev,video
ssh-import-id: None
plain_text_passwd: pi
lock_passwd: true
ssh_pwauth: true
chpasswd: expire: false
ssh-authorized-keys:
- ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local
Here's another variation that aligns the values
def yamlify2:
(objects | to_entries | (map(.key | length) | max + 2) as $w |
. | (.value | type) as $type |
if $type == "array" then
"(.key):", (.value | yamlify2)
elif $type == "object" then
"(.key):", " (.value | yamlify2)"
else
"(.key):(" " * (.key | $w - length))(.value)"
end
)
// (arrays | select(length > 0) | [yamlify2] |
" - (.[0])", " (.[1:])"
)
// .
;
$ jq -r yamlify2 input.json
users:
- name: pi
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: users,docker,video
plain_text_passwd: pi
lock_passwd: false
ssh_pwauth: true
chpasswd:
expire: false
- name: admin
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
primary-group: users
groups: users,docker,adm,dialout,audio,plugdev,netdev,video
ssh-import-id: None
plain_text_passwd: pi
lock_passwd: true
ssh_pwauth: true
chpasswd: expire: false
ssh-authorized-keys:
- ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local
I'm not sure what rules you're using to get to your expected result. It seems like you're randomly applying different rules to how the values are being converted.
As I understand it, scalar values are just output as is (with potential encoding), objects are output as key/value pairs, and array objects are output with a -
for every item. The indentation associates what's part of what.
So based on those rules if you're going to use jq:
def yamlify:
(objects | to_entries | (.value | type) as $type |
if $type == "array" then
"(.key):", (.value | yamlify)
elif $type == "object" then
"(.key):", " (.value | yamlify)"
else
"(.key):t(.value)"
end
)
// (arrays | select(length > 0) | [yamlify] |
" - (.[0])", " (.[1:])"
)
// .
;
Then to use it, add it to your .jq
file and use it:
$ jq -r yamlify input.json
users:
- name: pi
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: users,docker,video
plain_text_passwd: pi
lock_passwd: false
ssh_pwauth: true
chpasswd:
expire: false
- name: admin
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
primary-group: users
groups: users,docker,adm,dialout,audio,plugdev,netdev,video
ssh-import-id: None
plain_text_passwd: pi
lock_passwd: true
ssh_pwauth: true
chpasswd: expire: false
ssh-authorized-keys:
- ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local
Here's another variation that aligns the values
def yamlify2:
(objects | to_entries | (map(.key | length) | max + 2) as $w |
. | (.value | type) as $type |
if $type == "array" then
"(.key):", (.value | yamlify2)
elif $type == "object" then
"(.key):", " (.value | yamlify2)"
else
"(.key):(" " * (.key | $w - length))(.value)"
end
)
// (arrays | select(length > 0) | [yamlify2] |
" - (.[0])", " (.[1:])"
)
// .
;
$ jq -r yamlify2 input.json
users:
- name: pi
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
groups: users,docker,video
plain_text_passwd: pi
lock_passwd: false
ssh_pwauth: true
chpasswd:
expire: false
- name: admin
gecos: Hypriot Pirate
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
primary-group: users
groups: users,docker,adm,dialout,audio,plugdev,netdev,video
ssh-import-id: None
plain_text_passwd: pi
lock_passwd: true
ssh_pwauth: true
chpasswd: expire: false
ssh-authorized-keys:
- ssh-rsa abcdefg1234567890 YOUR_KEY@YOURHOST.local
edited Nov 16 '18 at 19:17
answered Nov 16 '18 at 1:36
Jeff MercadoJeff Mercado
92.9k19186215
92.9k19186215
add a comment |
add a comment |
I ended up installing a gem and using ruby:
gem install deep_merge
(https://github.com/danielsdeleo/deep_merge)
Here is my approach:
#!/usr/bin/env ruby
#
require 'json'
require 'yaml'
require 'deep_merge/rails_compat'
json_input_file = ARGF.argv[0]
yaml_output_file = ARGF.argv[1]
scope = ARGF.argv[2]
json = File.read(json_input_file)
yaml = File.read(yaml_output_file)
json_data = JSON.parse(json)
scoped_result = json_data[scope]
old_values_hash = YAML.load(File.read(yaml_output_file))
result = YAML.parse(yaml)
merged = old_values_hash.deeper_merge scoped_result
File.write(yaml_output_file, merged.to_yaml)
It then can be used to read a specific scoped_value
from a json file.
jsonyaml.sh $JSON_FILE $YAML_TARGET "my_scope_to_add"
add a comment |
I ended up installing a gem and using ruby:
gem install deep_merge
(https://github.com/danielsdeleo/deep_merge)
Here is my approach:
#!/usr/bin/env ruby
#
require 'json'
require 'yaml'
require 'deep_merge/rails_compat'
json_input_file = ARGF.argv[0]
yaml_output_file = ARGF.argv[1]
scope = ARGF.argv[2]
json = File.read(json_input_file)
yaml = File.read(yaml_output_file)
json_data = JSON.parse(json)
scoped_result = json_data[scope]
old_values_hash = YAML.load(File.read(yaml_output_file))
result = YAML.parse(yaml)
merged = old_values_hash.deeper_merge scoped_result
File.write(yaml_output_file, merged.to_yaml)
It then can be used to read a specific scoped_value
from a json file.
jsonyaml.sh $JSON_FILE $YAML_TARGET "my_scope_to_add"
add a comment |
I ended up installing a gem and using ruby:
gem install deep_merge
(https://github.com/danielsdeleo/deep_merge)
Here is my approach:
#!/usr/bin/env ruby
#
require 'json'
require 'yaml'
require 'deep_merge/rails_compat'
json_input_file = ARGF.argv[0]
yaml_output_file = ARGF.argv[1]
scope = ARGF.argv[2]
json = File.read(json_input_file)
yaml = File.read(yaml_output_file)
json_data = JSON.parse(json)
scoped_result = json_data[scope]
old_values_hash = YAML.load(File.read(yaml_output_file))
result = YAML.parse(yaml)
merged = old_values_hash.deeper_merge scoped_result
File.write(yaml_output_file, merged.to_yaml)
It then can be used to read a specific scoped_value
from a json file.
jsonyaml.sh $JSON_FILE $YAML_TARGET "my_scope_to_add"
I ended up installing a gem and using ruby:
gem install deep_merge
(https://github.com/danielsdeleo/deep_merge)
Here is my approach:
#!/usr/bin/env ruby
#
require 'json'
require 'yaml'
require 'deep_merge/rails_compat'
json_input_file = ARGF.argv[0]
yaml_output_file = ARGF.argv[1]
scope = ARGF.argv[2]
json = File.read(json_input_file)
yaml = File.read(yaml_output_file)
json_data = JSON.parse(json)
scoped_result = json_data[scope]
old_values_hash = YAML.load(File.read(yaml_output_file))
result = YAML.parse(yaml)
merged = old_values_hash.deeper_merge scoped_result
File.write(yaml_output_file, merged.to_yaml)
It then can be used to read a specific scoped_value
from a json file.
jsonyaml.sh $JSON_FILE $YAML_TARGET "my_scope_to_add"
answered Nov 15 '18 at 19:21
JanJan
2,2231944
2,2231944
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53315791%2fhow-to-convert-a-json-response-into-yaml-in-bash%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
You can use
python
/perl
which have in-builtYAML
andJSON
modules - commandlinefu.com/commands/view/12218/convert-yaml-to-json– Inian
Nov 15 '18 at 9:11
That's exact the opposite direction
– Jan
Nov 15 '18 at 9:18
1
Bash itself is not a good platform for this. Find an existing tool, or write one in e.g. Python. Depending on your preferred language, it should not be hard to find an existing question on Stack Overflow with suggestions; here's a search for Python
– tripleee
Nov 15 '18 at 10:04
Please follow the Minimal, Complete, and Verifiable example guidelines. In particular, a sample my.yml (i.e. input) would be helpful.
– peak
Nov 15 '18 at 10:17
yq r input.json
should do the job.– AHT
Nov 15 '18 at 18:15