How to search json for a string and output a parent value using jq?

Issue

Trying to pull a value out with jq, but didn’t seem as easy as i originally thought.

I have a variable of CAR="baga6e~tlwdcmli__QmbHKa~G65fMXzh.car".

How can i use this variable to return the parent "piece_cid" ?

Example: Using a bash varible of $CAR with a value of baga6e~tlwdcmli__QmbHKa~G65fMXzh.car, id be able to get the results saved to $PIECE_CID with a value of baga6ea4seaqa24ucggxkliw4la4tkgvhevv3dacavovghsmnnscclt4tlwdcmli

I tried some commands and been googling for about 2 hours but nothing has came up for what im seeking. Completely new to jq. Hopefully someone can push me in right direction?

{
  "response_code": 200,
  "response_entries": 2,
  "response": [
    {
      "piece_cid": "baga6ea4seaqa24ucggxkliw4la4tkgvhevv3dacavovghsmnnscclt4tlwdcmli",
      "dataset": "genome-ark",
      "padded_piece_size": 34359738368,
      "payload_cids": [
        "QmbHKaq6z321PqEG1BVLEAMpapq6YjkhdXpcs3G65fMXzh"
      ],
      "sources": [
        {
          "source_type": "Filecoin",
          "provider_id": "f0402371",
          "deal_id": 1928414,
          "original_payload_cid": "QmbHKaq6z321PqEG1BVLEAMpapq6YjkhdXpcs3G65fMXzh",
          "deal_expiration": "2022-05-22T21:14:30Z",
          "is_filplus": false,
          "sector_id": null,
          "sector_expires": null,
          "sample_retrieve_cmd": "lotus client retrieve --provider f0402371 --maxPrice 0 --allow-local --car 'QmbHKaq6z321PqEG1BVLEAMpapq6YjkhdXpcs3G65fMXzh' $(pwd)/baga6e~tlwdcmli__QmbHKa~G65fMXzh.car"
        }
      ],
      "sample_request_cmd": "echo curl -sLH \"Authorization: $( ./fil-spid.bash f01826669 )\" https://api.evergreen.filecoin.io/request_piece/baga6ea4seaqa24ucggxkliw4la4tkgvhevv3dacavovghsmnnscclt4tlwdcmli | sh"
    },
    {
      "piece_cid": "baga6ea4seaqa2acwhwril5pm6n4muqlsrdkk27cgrqowz67himgbcwc3jhitina",
      "dataset": "genome-ark",
      "padded_piece_size": 34359738368,
      "payload_cids": [
        "QmSJc7g8sdUZKt2MqSDnrd1DXxxHow6XwKQZLcoCoCeW42"
      ],
      "sources": [
        {
          "source_type": "Filecoin",
          "provider_id": "f0402371",
          "deal_id": 1927852,
          "original_payload_cid": "QmSJc7g8sdUZKt2MqSDnrd1DXxxHow6XwKQZLcoCoCeW42",
          "deal_expiration": "2022-05-22T20:11:00Z",
          "is_filplus": false,
          "sector_id": null,
          "sector_expires": null,
          "sample_retrieve_cmd": "lotus client retrieve --provider f0402371 --maxPrice 0 --allow-local --car 'QmSJc7g8sdUZKt2MqSDnrd1DXxxHow6XwKQZLcoCoCeW42' $(pwd)/baga6e~3jhitina__QmSJc7~oCoCeW42.car"
        }
      ],
      "sample_request_cmd": "echo curl -sLH \"Authorization: $( ./fil-spid.bash f01826669 )\" https://api.evergreen.filecoin.io/request_piece/baga6ea4seaqa2acwhwril5pm6n4muqlsrdkk27cgrqowz67himgbcwc3jhitina | sh"
    }
  ]
}

Solution

Depending on what level you can expect your search value, here’s a quite narrow solution using all keys from the example: First, iterate over the .response array, then keep only those items for which any of the values in .sources[].sample_retrieve_cmd contains the given string, then output the value of .piece_cid as raw text using -r.

CAR="baga6e~tlwdcmli__QmbHKa~G65fMXzh.car"
jq -r --arg car "$CAR" '
  .response[]
  | select(any(.sources[].sample_retrieve_cmd; contains($car)))
  | .piece_cid
'
baga6ea4seaqa24ucggxkliw4la4tkgvhevv3dacavovghsmnnscclt4tlwdcmli

Demo


Edit: To save the output into a variable just wrap the jq call as command substitution $() and assign the result to your variable:

PIECE_CID="$(jq -r --arg …)"

But keep in mind that (theoretically) more than one match could be present, which the solution from above would print out linewise (giving you a newline-delimited list of results in your bash variable).

Note: Avoid using uppercase variable names in Bash.

Answered By – pmf

Answer Checked By – Jay B. (AngularFixing Admin)

Leave a Reply

Your email address will not be published.