1 unstable release

new 0.1.0 Mar 9, 2025

#332 in Command line utilities

43 downloads per month

MIT license

195KB
1K SLoC

Jgrep

A mix between grep and jq

Look for partial text, and wildcard matches in JSON files.

Because jq forces you to know the entire path, and grep makes the match lose its JSON context.

Image


⚠️ The query language is experimental, and bound to change. ⚠️

If you want to make suggestions, discussion is welcomed in the issues

Usage

We will use the following JSON for all the examples:

{
  "items": [
    {
      "id": 1,
      "name": "Lorem",
      "active": true,
      "meta": {
        "rating": 4.7,
        "author": { "name": "John", "verified": false }
      }
    },
    {
      "id": 2,
      "name": "Ipsum",
      "active": false,
      "meta": {
        "rating": 3.9,
        "author": { "name": "Jane", "verified": true }
      }
    }
  ]
}

Query language

Jgrep uses a very simple query language, based on the JSON path syntax, and admitting wildcards (* and ?) for keys and values.

jgrep 'Jane' filename
#> .items[1].meta.author.name: "Jane"

Will look for all the occurrences of 'Jane', in keys or values, and it will return the path to it.

You can also look for keys only, by putting the keys before a colon (:), or starting it with a dot (.):

jgrep 'author:' filename
# or
jgrep '.meta.author' filename
#> .items[0].meta.author: { 
#>   "name": "John", 
#>   "verified": false 
#> }
#> .items[1].meta.author: {
#>   "name": "Jane",
#>   "verified": true 
#> }

Or for values only, by putting the value after a colon:

jgrep ': true' filename
#> .items[0].active: true
#> .items[1].meta.author.verified: true

Or for values and keys, having the key before a colon and the value after it:

jgrep '.rating: 4.7' filename
#> .items[0].meta.rating: 4.7

And you can use wildcards:

jgrep '.name: J*n*' filename
#> .items[0].meta.author.name: "John"
#> .items[1].meta.author.name: "Jane"
jgrep '.name: Jan?' filename
#> .items[1].meta.author.name: "Jane"

Wildcards work with numbers too:

jgrep '.rating: 4.*' filename
#> .items[0].meta.rating: 4.7

Future features:

Flags

Displaying JSON instead of the path

If you want to see the whole matched json, not just the path to the matched part, use the --json (-j) flag. The path to the current match will be displayed in a different color, if the terminal supports it.

jgrep '.rating' filename -j
#> {
#>   "items": [
#>     {
#>       "meta": {
#>         "rating": 4.7
#>       }
#>     },
#>     {
#>       "meta": {
#>         "rating": 3.9
#>       }
#>     },
#>   ]
#> }

Context

Like for grep, --context (-C) displays information around the match. In jgrep, each context prints one previous level of the JSON object. The path to the current match will be displayed in a different color, if the terminal supports it.

jgrep 'Jane' filename -C 1
#> .items[1].meta.author: {
#>   "name": "Jane", 
#>   "verified": true 
#> }

Ignore case

You can use the --ignore-case (-i) flag to ignore the case of the query.

jgrep 'jane' filename -i
#> .items[1].meta.author.name: "Jane"

Dependencies

~3–10MB
~105K SLoC