skip to Main Content

I have an array of objects as input, each object looking as follows:

{
  "downloadDir": "/merge/downloads",
  "id": 2485,
  "labels": [
    "irrelevant",
    "downloads"
  ]
}

I am trying to have JQ go through every object and find those, which do not have an element in the .labels array that is a substring of .downloadDir between 1st and 2nd ‘/’, i.e.

  • for "/merge/downloads" it should be "downloads"
  • for "/merge/tv/downloads" it should be "tv"
  • for "/merge/tv-share/downloads" it should be "tv-share"

For matching objects it should return their .id.

Having reviewed some similar questions on Stack Overflow, I’m thinking the logic is supposed to look something like this: map(select(.labels | index(.downloadDir))). This works if I have a static string in index(), like map(select(.labels | index("downloads"))), however I can’t get it to work with .downloadDir: it throws out "Cannot index array with string "downloadDir"" or "Cannot index string with string "labels"", depending on whether I pass the input as an array or not.

I am entirely unsure how to approach applying a regex to .downloadDir to grab the needed substring from it.

2

Answers


  1. I added one more object into the input for testing:

    [{
      "downloadDir": "/merge/downloads",
      "id": 2485,
      "labels": [
        "irrelevant",
        "downloads"
      ]
    },{
      "downloadDir": "/merge/tv/downloads",
      "id": 2486,
      "labels": [
        "irrelevant",
        "downloads"
      ]
    }]
    

    The following expression returned the id of the first object, not the second:

    <file.json jq '.[]
                   | (.downloadDir | split("/")[2]) as $key
                   | select(.labels | map(. != $key) | all).id'
    
    Login or Signup to reply.
  2. Split the .downloadDir at "/" using /, and take the second item. Compare it to each item in .labels and yield true if at least one (any) matches. select those items, and output the .id.

    jq 'select(any(.labels[] == (.downloadDir / "/")[2]; .)).id ' input.json
    
    2485
    

    Demo

    This works on a stream of items (as suggested by your sample). If your input is indeed an array of items, prepend .[].

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search