michaelcoyote
michaelcoyote

Reputation: 161

Filtering one key with the value from another key in jq

I've got a list of package data in JSON format that looks like:

[
  {
    "Package": "pyasn1",
    "Version": "0.4.6",
    "DownloadURL": "https://files.pythonhosted.org/packages/3d/50/5ce5dbe42eaf016cb9b062caf6d0f38018454756d4feb467de3e29431dae/pyasn1-0.4.6-py2.4.egg"
  },
  {
    "Package": "cachetools",
    "Version": "3.1.1",
    "DownloadURL": "https://files.pythonhosted.org/packages/08/6a/abf83cb951617793fd49c98cb9456860f5df66ff89883c8660aa0672d425/cachetools-4.0.0-py3-none-any.whl"
  }
]

And I'd like to generate a list of items where .DownloadURL doesn't contain the string in .Version.

I've tried this but it doesn't seem to work:

jq '.[]|select(.DownloadURL | contains(.Version)| not)'

I get the following error:

jq: error (at <stdin>:11): Cannot index string with string "Version"
exit status 5

I was able to do the following...

jq '.[]|select(.DownloadURL | contains("0.4.6")| not)'

...and it gave the results I would expect:

{
  "Package": "cachetools",
  "Version": "3.1.1",
  "DownloadURL": "https://files.pythonhosted.org/packages/08/6a/abf83cb951617793fd49c98cb9456860f5df66ff89883c8660aa0672d425/cachetools-4.0.0-py3-none-any.whl"
}

Is there a way to use the contents of .Version with the contains() function or is there a better way to do this? I've set up a playground with the data here.

Thanks!

Upvotes: 0

Views: 132

Answers (2)

Thomas__
Thomas__

Reputation: 330

The following has worked for me:

jq '.[]|.Version as $v|select(.DownloadURL | contains($v)| not)'
{
  "Package": "cachetools",
  "Version": "3.1.1",
  "DownloadURL": "https://files.pythonhosted.org/packages/08/6a/abf83cb951617793fd49c98cb9456860f5df66ff89883c8660aa0672d425/cachetools-4.0.0-py3-none-any.whl"
}

Is the result

Upvotes: 3

peak
peak

Reputation: 117027

I'd like to generate a list of items where .DownloadURL doesn't contain the string in .Version.

If as you say you want the result as a list, you could use map:

map(select( .Version as $v | .DownloadURL | contains($v) | not))

However, the semantics of contains is very complex so you might wish to consider using index instead:

map(select( .Version as $v | .DownloadURL | index($v) | not))

Upvotes: 1

Related Questions