See also: Show HN: Turn your fzf into a live REPL (paweldu.dev)
#!/usr/bin/env bash
csv_filter() {
# csv_filter <file|stdin>
# interactively filters a csv-column via case-insensitive regex
local data=${1:-'-'}
if [ "$data" = "-" ]; then
local data=$(mktemp)
cp /dev/stdin "$data"
fi
headers=$(head -1 < "$data" | csvquote)
colname=$(
echo "$headers" \
| awk -v RS=',' '{print NR, $0}' \
| grep . \
| fzf --prompt "column-to-filter: " \
--preview-window='down:80%' --preview "batcat -p --language 'csv' \
--color=always --line-range=:50 \"$data\""
)
colnum=$(echo "$colname" | cut -d ' ' -f 1)
reggie=$(
csvquote < "$data" \
| awk -v colnum="$colnum" -F, '!seen[$colnum]++ { print $colnum }' \
| fzf --prompt "$colname ~ " \
--print-query --preview-window='down:80%' --preview \
"csvquote < \"$data\" \
| awk -v colnum=\"$colnum\" -v reggie={q} -F, \
'{ IGNORECASE=1; if (NR==1) { print \$0 } else if (\$colnum ~ reggie) { print \$0 } }' \
| batcat -p --language 'csv' --color=always" | head -1
)
csvquote < "$data" \
| awk -v colnum="$colnum" -v reggie="$reggie" -F, \
'{ IGNORECASE=1; if (NR==1) { print $0 } else if ($colnum ~ reggie) { print $0 } }'
}
alias csv-filter=csv_filter