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
--historysaves the selected filters to this file, it enable going to the previous selection withCTRL-NandCTRL-P. The history file is also used to provide options to pick from.--promptshows a customized prompt--bindbinds an event or a keybinding to an action, checkfzfdocumentation for complete list. Here is used to scroll the preview, to update the preview title, and to select a filter.--headertext that is presented above the query--querythe 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