Home > OS >  How to search within sections of a JSON File?S
How to search within sections of a JSON File?S

Time:10-25

So, lets say I had a JSON File like this:

{
 "content": [
 {
  "word": "cat"
  "adjectives": [
   {
    "type": "textile"
    "adjective": "fluffy"
   },
   {
    "type": "visual"
    "adjective": "small"
   }
  ]
{
  "word": "chocolate"
  "adjectives": [
   {
    "type": "visual"
    "adjective": "small"
   },
   {
    "type": "gustatory"
    "adjective": "sweet"
   }
  ]
}

Now, say I wanted to search for two words. For example, "Fluffy" and "Small." The problem with this is that both words' adjectives contain small, and so I would have to manually search for which one contains fluffy. So, how would I do this in a quicker manner?

In other words, how would I find the word(s) with both "fluffy" and "small"

CodePudding user response:

A command-line solution would be to use jq:

jq -r '.content[] | select(.adjectives[].adjective == "fluffy") | .word' /pathToJsonFile.json

Output:

cat

Are you looking for something like this? Do you need a solution that uses other programming languages?

(P.S. your JSON example appears to be invalid)

CodePudding user response:

Since is now fair game (this was only clarified later in the comments), here is one solution using jq.

First, fix the JSON to be actually valid:

{
  "content": [
    {
      "word": "cat",
      "adjectives": [
        {
          "type": "textile",
          "adjective": "fluffy"
        },
        {
          "type": "visual",
          "adjective": "small"
        }
      ]
    },
    {
      "word": "dog",
      "adjectives": [
        {
          "type": "textile",
          "adjective": "fluffy"
        },
        {
          "type": "visual",
          "adjective": "big"
        }
      ]
    },
    {
      "word": "chocolate",
      "adjectives": [
        {
          "type": "visual",
          "adjective": "small"
        },
        {
          "type": "gustatory",
          "adjective": "sweet"
        }
      ]
    }
  ]
}

Then, the following jq filter returns an array containing the words which contain both adjectives:

.content
| map(
    select(
        .adjectives as $adj
        | all("small","fluffy"; IN($adj[].adjective))
    )
    | .word
)

If a non-array output is required, and only one word per line, use .[] instead of map (either after content or as a final filter), e.g.:

jq -r '.content[]
    | select(
        .adjectives as $adj
        | all("small","fluffy"; IN($adj[].adjective))
    )
    | .word'
  • Related