How to convert a json response into yaml in bash










1















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...










share|improve this question



















  • 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











  • 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















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...










share|improve this question



















  • 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











  • 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








1








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...










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 15 '18 at 9:17







Jan

















asked Nov 15 '18 at 9:05









JanJan

2,2231944




2,2231944







  • 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











  • 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





    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






  • 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












2 Answers
2






active

oldest

votes


















0














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





share|improve this answer
































    -1














    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"






    share|improve this answer






















      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
      );



      );













      draft saved

      draft discarded


















      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









      0














      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





      share|improve this answer





























        0














        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





        share|improve this answer



























          0












          0








          0







          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





          share|improve this answer















          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






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 16 '18 at 19:17

























          answered Nov 16 '18 at 1:36









          Jeff MercadoJeff Mercado

          92.9k19186215




          92.9k19186215























              -1














              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"






              share|improve this answer



























                -1














                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"






                share|improve this answer

























                  -1












                  -1








                  -1







                  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"






                  share|improve this answer













                  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"







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 15 '18 at 19:21









                  JanJan

                  2,2231944




                  2,2231944



























                      draft saved

                      draft discarded
















































                      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.




                      draft saved


                      draft discarded














                      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





















































                      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







                      這個網誌中的熱門文章

                      Barbados

                      How to read a connectionString WITH PROVIDER in .NET Core?

                      Node.js Script on GitHub Pages or Amazon S3