I’ve just shown how to make ssh interactive with Fzf. Let’s see how to make jq interactive!

In essence, it is exactly replicating jqplay’s features.

1. Fzf extra value proposition

When I previously said that fzf’s value proposition is to filter a list of lines interactively, I didn’t mention that it can much more than just that!

In particular, fzf can display both the list of lines to filter, and a sidebar running any command you like.

A common use of this feature is to filter the list of packages available in your distribution, and displaying some information about the selected package to help the user select the right one. Or as a preview of the file content when filtering files.

That last use case is what the feature is called: --preview.

Here is a simple example filtering a list of names, and greeting it in the sidebar:

echo -e 'name1\nname2\nname3' | fzf --preview 'echo hello {}'

2. Interactive jq

Jqplay helps you write your jq query by giving you an interactive environment.

We need a way to tell fzf to change its behaviour a bit:

  1. take the json as input

  2. do not filter it (--disabled)

  3. use the filter value as a jq query ({q})

  4. set a default value for fzf’s query to be a valid jq query (--query='.')

  5. apply that jq query to the json file, and display it in the sidebar (--preview)

  6. print the query, and not the result of the filter. (--print-query)

In here is the result:

jq '.' example.json | fzf --disabled --print-query --preview 'jq {q} example.json' --query='.' --no-sort --tac | head -1

In action, it displays the formatted input json on the left, the query at the bottom, and the result of that query on the right:

                                        │ 1615024086                           │
                                        │                                      │
                                        │                                      │
                                        │                                      │
  {                                     │                                      │
    "abbreviation": "-03",              │                                      │
    "client_ip": "",        │                                      │
    "datetime": "2021-03-06T06:48:06... │                                      │
    "day_of_week": 6,                   │                                      │
    "day_of_year": 65,                  │                                      │
    "dst": false,                       │                                      │
    "dst_from": null,                   │                                      │
    "dst_offset": 0,                    │                                      │
    "dst_until": null,                  │                                      │
    "raw_offset": -10800,               │                                      │
    "timezone": "America/Argentina/Sa.. │                                      │
    "unixtime": 1615024086,             │                                      │
    "utc_datetime": "2021-03-06T09:48.. │                                      │
    "utc_offset": "-03:00",             │                                      │
    "week_number": 9                    │                                      │
  }                                     │                                      │
  17/17                                 │                                      │
> .unixtime                             ╰──────────────────────────────────────╯

This offers at least 2 advantages compared to jqplay.org:

  • it’s faster (saving the network requests);

  • it’s private (not sending your json to some untrusted server).

Feel free to assign the jqplay alias in your terminal!

3. Conclusion

Even though jq and fzf together may seem incompatible at first sight, it ends up working extremely well.