2

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"
peak
  • 105,803
  • 17
  • 152
  • 177
Sukh
  • 85
  • 2
  • 9
  • As an aside, all-caps names are specified for use by variables meaningful to the shell and POSIX-specified tools, whereas lowercase names are reserved for application use and guaranteed not to have unintended consequences on the behavior of POSIX-y tools when defined. See http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html: *The name space of environment variable names containing lowercase letters is reserved for applications. Applications can define any environment variables with names from this name space without modifying the behavior of the standard utilities.* – Charles Duffy Sep 20 '18 at 17:29
  • ...keeping in mind that defining a shell variable overwrites any like-named environment variable, so namespace rules necessarily apply to both. Making a habit of following that rule prevents making mistakes like `for PATH in /foo/bar/*; do ...` leaving your shell unable to run external programs. – Charles Duffy Sep 20 '18 at 17:29

1 Answers1

5

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.

peak
  • 105,803
  • 17
  • 152
  • 177
  • Thanks this has worked. I always thought once I declared --arg once it automatically works for other variables I did try $test1 however I did not add in another --arg before this thanks and it kept errors that test1 is not declared on line one, thanks for pointing that out. – Sukh Sep 21 '18 at 05:13