jq update list elements based on values









up vote
-1
down vote

favorite












Is it possible to use jq to turn the following JSON data



[

"a": null,
"b": [

"c": "cc",
"d": "dd1"
,

"c": "cc",
"d": "dd1",
"e": "ee",
"f": "ff"

]
,

"b": [

"c": "cc",
"d": "dd2",
"e": "ee",
"f": "ff"

]

]


into



[

"a": null,
"b": [
[
"cc", "d1"
],
[
"cc", "d1", "ff"
]
]
,

"b": [
[
"cc", "d2", "ff"
]
]

]


?



Note that the purpose is to reduce the b list with certain elements of its items based on a condition. The condition assigns the string d1 if the value of d is dd1, otherwise d2 is assigned if dd2 is present.



The following unsuccessful attempt demonstrates the idea:



$ jq -r '..b = [..b.c, ?, ..b.f?]'









share|improve this question























  • what have you tried so far?
    – oguzismail
    Nov 11 at 16:09










  • @oguzismail See the updated question. I am unaware how to address the conditional part and how to update each element individually.
    – dfernan
    Nov 11 at 16:34















up vote
-1
down vote

favorite












Is it possible to use jq to turn the following JSON data



[

"a": null,
"b": [

"c": "cc",
"d": "dd1"
,

"c": "cc",
"d": "dd1",
"e": "ee",
"f": "ff"

]
,

"b": [

"c": "cc",
"d": "dd2",
"e": "ee",
"f": "ff"

]

]


into



[

"a": null,
"b": [
[
"cc", "d1"
],
[
"cc", "d1", "ff"
]
]
,

"b": [
[
"cc", "d2", "ff"
]
]

]


?



Note that the purpose is to reduce the b list with certain elements of its items based on a condition. The condition assigns the string d1 if the value of d is dd1, otherwise d2 is assigned if dd2 is present.



The following unsuccessful attempt demonstrates the idea:



$ jq -r '..b = [..b.c, ?, ..b.f?]'









share|improve this question























  • what have you tried so far?
    – oguzismail
    Nov 11 at 16:09










  • @oguzismail See the updated question. I am unaware how to address the conditional part and how to update each element individually.
    – dfernan
    Nov 11 at 16:34













up vote
-1
down vote

favorite









up vote
-1
down vote

favorite











Is it possible to use jq to turn the following JSON data



[

"a": null,
"b": [

"c": "cc",
"d": "dd1"
,

"c": "cc",
"d": "dd1",
"e": "ee",
"f": "ff"

]
,

"b": [

"c": "cc",
"d": "dd2",
"e": "ee",
"f": "ff"

]

]


into



[

"a": null,
"b": [
[
"cc", "d1"
],
[
"cc", "d1", "ff"
]
]
,

"b": [
[
"cc", "d2", "ff"
]
]

]


?



Note that the purpose is to reduce the b list with certain elements of its items based on a condition. The condition assigns the string d1 if the value of d is dd1, otherwise d2 is assigned if dd2 is present.



The following unsuccessful attempt demonstrates the idea:



$ jq -r '..b = [..b.c, ?, ..b.f?]'









share|improve this question















Is it possible to use jq to turn the following JSON data



[

"a": null,
"b": [

"c": "cc",
"d": "dd1"
,

"c": "cc",
"d": "dd1",
"e": "ee",
"f": "ff"

]
,

"b": [

"c": "cc",
"d": "dd2",
"e": "ee",
"f": "ff"

]

]


into



[

"a": null,
"b": [
[
"cc", "d1"
],
[
"cc", "d1", "ff"
]
]
,

"b": [
[
"cc", "d2", "ff"
]
]

]


?



Note that the purpose is to reduce the b list with certain elements of its items based on a condition. The condition assigns the string d1 if the value of d is dd1, otherwise d2 is assigned if dd2 is present.



The following unsuccessful attempt demonstrates the idea:



$ jq -r '..b = [..b.c, ?, ..b.f?]'






json jq






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 11 at 16:32

























asked Nov 11 at 15:39









dfernan

215716




215716











  • what have you tried so far?
    – oguzismail
    Nov 11 at 16:09










  • @oguzismail See the updated question. I am unaware how to address the conditional part and how to update each element individually.
    – dfernan
    Nov 11 at 16:34

















  • what have you tried so far?
    – oguzismail
    Nov 11 at 16:09










  • @oguzismail See the updated question. I am unaware how to address the conditional part and how to update each element individually.
    – dfernan
    Nov 11 at 16:34
















what have you tried so far?
– oguzismail
Nov 11 at 16:09




what have you tried so far?
– oguzismail
Nov 11 at 16:09












@oguzismail See the updated question. I am unaware how to address the conditional part and how to update each element individually.
– dfernan
Nov 11 at 16:34





@oguzismail See the updated question. I am unaware how to address the conditional part and how to update each element individually.
– dfernan
Nov 11 at 16:34













2 Answers
2






active

oldest

votes

















up vote
0
down vote













This is probably not the best way to do what you want, but it does get the desired output and it has the conditional you asked about.



jq '..b |= map(
[ .c,
(if .d == "dd1" then "d1" elif .d == "dd2" then "d2" else . end),
.f // empty
] )'





share|improve this answer



























    up vote
    0
    down vote













    Without changing the value of the d key, you would use this jq filter:



    jq '..b|=(to_entries|map(.value))' file


    That updates the b array into all values of the inner objects.



    If you want to update the d, you could use this filter:



    jq '..b |= (to_entries|
    map(
    if(.key=="d") then
    .value|=sub("d+";"d")
    else .
    end
    |.value)
    )' file


    that adds a check if the key is d the associated value is updated to remove the duplicated d character from the string. This requires jq to support for regex (to be able to use the sub function).






    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',
      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%2f53250318%2fjq-update-list-elements-based-on-values%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








      up vote
      0
      down vote













      This is probably not the best way to do what you want, but it does get the desired output and it has the conditional you asked about.



      jq '..b |= map(
      [ .c,
      (if .d == "dd1" then "d1" elif .d == "dd2" then "d2" else . end),
      .f // empty
      ] )'





      share|improve this answer
























        up vote
        0
        down vote













        This is probably not the best way to do what you want, but it does get the desired output and it has the conditional you asked about.



        jq '..b |= map(
        [ .c,
        (if .d == "dd1" then "d1" elif .d == "dd2" then "d2" else . end),
        .f // empty
        ] )'





        share|improve this answer






















          up vote
          0
          down vote










          up vote
          0
          down vote









          This is probably not the best way to do what you want, but it does get the desired output and it has the conditional you asked about.



          jq '..b |= map(
          [ .c,
          (if .d == "dd1" then "d1" elif .d == "dd2" then "d2" else . end),
          .f // empty
          ] )'





          share|improve this answer












          This is probably not the best way to do what you want, but it does get the desired output and it has the conditional you asked about.



          jq '..b |= map(
          [ .c,
          (if .d == "dd1" then "d1" elif .d == "dd2" then "d2" else . end),
          .f // empty
          ] )'






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 11 at 19:10









          user197693

          50223




          50223






















              up vote
              0
              down vote













              Without changing the value of the d key, you would use this jq filter:



              jq '..b|=(to_entries|map(.value))' file


              That updates the b array into all values of the inner objects.



              If you want to update the d, you could use this filter:



              jq '..b |= (to_entries|
              map(
              if(.key=="d") then
              .value|=sub("d+";"d")
              else .
              end
              |.value)
              )' file


              that adds a check if the key is d the associated value is updated to remove the duplicated d character from the string. This requires jq to support for regex (to be able to use the sub function).






              share|improve this answer
























                up vote
                0
                down vote













                Without changing the value of the d key, you would use this jq filter:



                jq '..b|=(to_entries|map(.value))' file


                That updates the b array into all values of the inner objects.



                If you want to update the d, you could use this filter:



                jq '..b |= (to_entries|
                map(
                if(.key=="d") then
                .value|=sub("d+";"d")
                else .
                end
                |.value)
                )' file


                that adds a check if the key is d the associated value is updated to remove the duplicated d character from the string. This requires jq to support for regex (to be able to use the sub function).






                share|improve this answer






















                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  Without changing the value of the d key, you would use this jq filter:



                  jq '..b|=(to_entries|map(.value))' file


                  That updates the b array into all values of the inner objects.



                  If you want to update the d, you could use this filter:



                  jq '..b |= (to_entries|
                  map(
                  if(.key=="d") then
                  .value|=sub("d+";"d")
                  else .
                  end
                  |.value)
                  )' file


                  that adds a check if the key is d the associated value is updated to remove the duplicated d character from the string. This requires jq to support for regex (to be able to use the sub function).






                  share|improve this answer












                  Without changing the value of the d key, you would use this jq filter:



                  jq '..b|=(to_entries|map(.value))' file


                  That updates the b array into all values of the inner objects.



                  If you want to update the d, you could use this filter:



                  jq '..b |= (to_entries|
                  map(
                  if(.key=="d") then
                  .value|=sub("d+";"d")
                  else .
                  end
                  |.value)
                  )' file


                  that adds a check if the key is d the associated value is updated to remove the duplicated d character from the string. This requires jq to support for regex (to be able to use the sub function).







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 12 at 9:10









                  oliv

                  8,2281130




                  8,2281130



























                      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.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • 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%2f53250318%2fjq-update-list-elements-based-on-values%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







                      Popular posts from this blog

                      Top Tejano songwriter Luis Silva dead of heart attack at 64

                      ReactJS Fetched API data displays live - need Data displayed static

                      政党