jq fzf powered filtering
2023/11/18 09:39When needing to explore a JSON file for a long time I just reached into my history
and looked for a oneliner that I copied from a github gist echo '' | fzf --print-query --preview "cat *.json | jq {q}"
. This worked quite well, but I have now decided to improve it leveraging the fzf features.
Features
- Supports reading from stdin (pipe or
-
) and path - Keeps history of selected filters and presenting them as options for fzf.
- Prints the result of applying the filter the input
The script
function jqz () {
if [[ -z $1 ]] || [[ $1 == "-" ]]; then
input=$(mktemp)
trap "rm -f '$input'" EXIT
cat /dev/stdin > "$input"
else
input="$1"
fi
local q=$(<$HOME/.jqz-history \
| fzf \
--history=$HOME/.jqz-history \
--query '.' \
--prompt 'jq filter> ' \
--bind "tab:replace-query"\
--bind "return:print-query" \
--bind "alt-up:preview-page-up,alt-down:preview-page-down" \
--bind 'focus:transform-preview-label:echo [ {} ]' \
--header 'TAB: select filter' \
--preview "<$input | jq --color-output -r {q}")
jq -r "$q" "$input"
}
fzf options
--history
saves the selected filters to this file, it enable going to the previous selection withCTRL-N
andCTRL-P
. The history file is also used to provide options to pick from.--prompt
shows a customized prompt--bind
binds an event or a keybinding to an action, checkfzf
documentation for complete list. Here is used to scroll the preview, to update the preview title, and to select a filter.--header
text that is presented above the query--query
the default query
Supporting both stdin and paths
I got this part from Implementing a jq REPL with fzf it allows to pipe in json {"a":42} | jqz
or to read from a file jqz /tmp/some-file.json
if [[ -z $1 ]] || [[ $1 == "-" ]]; then
input=$(mktemp)
trap "rm -f '$input'" EXIT
cat /dev/stdin > "$input"
else
input="$1"
fi