jsonjqparameterization

How to pass a variable into JQ select/contains query


I am trying to pass two variables into a jq query.

My JSON

 {
 "AlbumTitle": "Name Of Album",
 "AlbumLink": "/album/link/id/1/album-name/",
 "ArtistName": "Artist Name",
 "Date": "September 14, 2018"
 },
 {
 "AlbumTitle": "Name Of Album",
 "AlbumLink": "/album/link/id/2/album-name/",
 "ArtistName": "Artist Name",
 "Date": "September 13, 2018"
 }

I two variables as the Date and Artist Name, and I am trying to pull back the ArtistLink depending on the variables.

I am using the JQ line below.

 cat test.json | jq -n -r --arg TESTDATE "$TESTDATE" '.. | objects | {select(.Date == '"$TESTDATE"')} | select(.ArtistName | contains('"$test1"')) | .AlbumLink'

And I am getting the error

 "jq: error: syntax error, unexpected '(', expecting '}'      (Unix shell quoting issues?) at <top-level>, line 1:
 .. | objects | {select(.Date == September 13, 2018)} | select(.ArtistName | contains(Artist)) | .AlbumLink                      
 jq: 1 compile error"

Solution

  • First, the shown input is neither valid JSON nor a valid stream of JSON documents. Since you've used ..|objects I'll assume your intent was that the input be an array.

    Second, the -n option means: don't automatically read STDIN or the specified file. Since you've used cat, I'll drop it.

    Third, you have used $TESTDATE and $test1 without giving sample values. I'm going to use the variables and values shown below.

    Fourth, it's generally best to pass in parameter values using the --arg or --argjson option, as you have done for $TESTDATE but not $test1.

    Fifth, it's a minor point, but I'm going to lose the cat: see Useless use of cat?

    Putting it all together, we could write:

    testdate="September 13, 2018"
    testname="Artist Name"
    
    < test.json jq -r --arg testdate "$testdate" --arg testname "$testname" '
        .[]
        | select((.Date == $testdate) and (.ArtistName | contains($testname)))
        | .AlbumLink '
    

    contains, however, is a funny beast, and generally I'd recommend using index instead.