cli-productivity

CLI Productivity Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "cli-productivity" with this command: npx skills add vamseeachanta/workspace-hub/vamseeachanta-workspace-hub-cli-productivity

CLI Productivity Skill

Master essential CLI tools and shell patterns for efficient terminal workflows. This skill covers modern replacements for traditional Unix tools, fuzzy finding, pipeline patterns, and shell customization.

When to Use This Skill

USE when:

  • Building efficient terminal workflows

  • Processing text and JSON data

  • Searching codebases quickly

  • Navigating file systems efficiently

  • Automating repetitive tasks

  • Creating shell functions and aliases

  • Building interactive scripts

DON'T USE when:

  • GUI-based workflows are more appropriate

  • Processing binary data (use specialized tools)

  • Complex data analysis (use Python/Pandas)

  • Tasks requiring visual feedback

Prerequisites

Installation

macOS (Homebrew):

Essential modern tools

brew install jq # JSON processor brew install fzf # Fuzzy finder brew install ripgrep # Fast grep (rg) brew install fd # Fast find brew install bat # Better cat brew install exa # Better ls (or eza) brew install zoxide # Smart cd brew install starship # Shell prompt brew install tmux # Terminal multiplexer

Install fzf keybindings

$(brew --prefix)/opt/fzf/install

Linux (Ubuntu/Debian):

Update package list

sudo apt-get update

Install from apt (may be older versions)

sudo apt-get install -y jq fzf ripgrep fd-find bat

Note: fd is 'fdfind' on Debian/Ubuntu

sudo ln -s $(which fdfind) /usr/local/bin/fd

bat may be 'batcat' on older systems

sudo ln -s $(which batcat) /usr/local/bin/bat

Install exa/eza

sudo apt-get install -y exa # or: cargo install eza

Install zoxide

curl -sS https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | bash

Install starship

curl -sS https://starship.rs/install.sh | sh

Arch Linux:

sudo pacman -S jq fzf ripgrep fd bat exa zoxide starship tmux

Verification:

Verify installations

for cmd in jq fzf rg fd bat exa zoxide starship; do command -v $cmd && echo "$cmd: OK" || echo "$cmd: NOT FOUND" done

Core Capabilities

  1. jq - JSON Processing

Basic Operations:

Pretty print JSON

echo '{"name":"John","age":30}' | jq '.'

Extract field

curl -s https://api.github.com/repos/nodejs/node | jq '.stargazers_count'

Filter arrays

echo '[1,2,3,4,5]' | jq '.[] | select(. > 2)'

Transform data

echo '{"first":"John","last":"Doe"}' | jq '{fullName: (.first + " " + .last)}'

Common jq Patterns:

Extract multiple fields

jq '{name: .name, stars: .stargazers_count}'

Array operations

jq '.items | length' # Count items jq '.items | first' # First item jq '.items | last' # Last item jq '.items[0:5]' # Slice first 5

Filtering

jq '.[] | select(.status == "active")' jq '.[] | select(.count > 100)' jq '.[] | select(.name | contains("test"))'

Sorting

jq 'sort_by(.date)' jq 'sort_by(.date) | reverse'

Grouping

jq 'group_by(.category)' jq 'group_by(.category) | map({key: .[0].category, count: length})'

Mapping

jq '.[] | {id, name}' jq 'map({id: .id, upper_name: (.name | ascii_upcase)})'

Shell Functions for jq:

Pretty print JSON file

jqp() { jq '.' "$1" | bat --language json }

Extract field from JSON file

jqf() { local file="$1" local field="$2" jq -r ".$field" "$file" }

Count items in JSON array

jqcount() { jq 'if type == "array" then length else 1 end' "$1" }

Filter JSON by field value

jqfilter() { local file="$1" local field="$2" local value="$3" jq --arg val "$value" ".[] | select(.$field == $val)" "$file" }

  1. fzf - Fuzzy Finder

Basic Usage:

Find and edit file

vim $(fzf)

Find with preview

fzf --preview 'bat --color=always {}'

Multi-select

fzf --multi

Filter with query

echo -e "apple\nbanana\norange" | fzf --query "an"

fzf Configuration:

Add to ~/.bashrc or ~/.zshrc

Default options

export FZF_DEFAULT_OPTS=' --height 40% --layout=reverse --border --preview-window=right:50%:wrap --bind=ctrl-d:preview-page-down --bind=ctrl-u:preview-page-up '

Use fd for faster file finding

export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git' export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" export FZF_ALT_C_COMMAND='fd --type d --hidden --follow --exclude .git'

Preview settings

export FZF_CTRL_T_OPTS='--preview "bat --color=always --style=numbers --line-range=:500 {}"' export FZF_ALT_C_OPTS='--preview "exa --tree --level=2 --color=always {}"'

Powerful fzf Functions:

Fuzzy edit file

fe() { local file file=$(fzf --preview 'bat --color=always --style=numbers --line-range=:500 {}') [[ -n "$file" ]] && ${EDITOR:-vim} "$file" }

Fuzzy cd into directory

fcd() { local dir dir=$(fd --type d --hidden --follow --exclude .git | fzf --preview 'exa --tree --level=2 --color=always {}') [[ -n "$dir" ]] && cd "$dir" }

Fuzzy kill process

fkill() { local pid pid=$(ps aux | sed 1d | fzf --multi | awk '{print $2}') [[ -n "$pid" ]] && echo "$pid" | xargs kill -9 }

Fuzzy git checkout branch

fco() { local branch branch=$(git branch -a --color=always | grep -v '/HEAD' | fzf --ansi | sed 's/^[* ]*//' | sed 's#remotes/origin/##') [[ -n "$branch" ]] && git checkout "$branch" }

Fuzzy git log

flog() { git log --oneline --color=always | fzf --ansi --preview 'git show --color=always {1}' | awk '{print $1}' }

Fuzzy history search

fh() { local cmd cmd=$(history | fzf --tac | sed 's/^[ ][0-9][ ]*//') [[ -n "$cmd" ]] && eval "$cmd" }

Fuzzy environment variable

fenv() { local var var=$(env | fzf | cut -d= -f1) [[ -n "$var" ]] && echo "${!var}" }

Fuzzy docker container

fdocker() { local container container=$(docker ps --format '{{.Names}}\t{{.Image}}\t{{.Status}}' | fzf | awk '{print $1}') [[ -n "$container" ]] && docker exec -it "$container" sh }

  1. ripgrep (rg) - Fast Search

Basic Usage:

Search for pattern

rg "function"

Case insensitive

rg -i "error"

Show line numbers

rg -n "TODO"

Search specific file types

rg --type py "import" rg -t js "require"

Exclude patterns

rg "pattern" --glob '!*.min.js' rg "pattern" --glob '!node_modules'

Advanced ripgrep:

Context lines

rg -C 3 "error" # 3 lines before and after rg -B 2 "error" # 2 lines before rg -A 2 "error" # 2 lines after

Fixed strings (no regex)

rg -F "func()"

Word boundaries

rg -w "log" # Match "log" not "logging"

Multiple patterns

rg -e "pattern1" -e "pattern2"

Files matching pattern

rg -l "TODO" # List files only rg -c "TODO" # Count matches per file

Inverse match

rg -v "DEBUG" # Lines NOT containing DEBUG

Replace

rg "old" --replace "new"

JSON output

rg --json "pattern" | jq '.'

Statistics

rg --stats "pattern"

ripgrep Functions:

Search and preview with fzf

rgs() { rg --color=always --line-number "$1" | fzf --ansi --preview 'bat --color=always $(echo {} | cut -d: -f1) --highlight-line $(echo {} | cut -d: -f2)' }

Search and open in editor

rge() { local selection selection=$(rg --color=always --line-number "$1" | fzf --ansi) if [[ -n "$selection" ]]; then local file=$(echo "$selection" | cut -d: -f1) local line=$(echo "$selection" | cut -d: -f2) ${EDITOR:-vim} "+$line" "$file" fi }

Search TODOs

todos() { rg --color=always "TODO|FIXME|HACK|XXX" "${1:-.}" | fzf --ansi }

Search function definitions

funcs() { rg --color=always "^(def |function |async function |const .* = |class )" "${1:-.}" | fzf --ansi }

  1. fd - Fast Find

Basic Usage:

Find files by name

fd "readme"

Find with extension

fd -e md fd -e py -e js

Find directories

fd -t d "src"

Find files

fd -t f "config"

Exclude patterns

fd -E node_modules -E .git

Hidden files

fd -H "config"

Execute command on results

fd -e log -x rm {} fd -e py -x wc -l {}

fd Functions:

Find and preview

fdp() { fd "$@" | fzf --preview 'bat --color=always {} 2>/dev/null || exa --tree --level=2 --color=always {}' }

Find and edit

fde() { local file file=$(fd -t f "$@" | fzf --preview 'bat --color=always {}') [[ -n "$file" ]] && ${EDITOR:-vim} "$file" }

Find large files

fdlarge() { local size="${1:-100M}" fd -t f -S +"$size" | xargs ls -lh | sort -k5 -h }

Find recent files

fdrecent() { local days="${1:-7}" fd -t f --changed-within "${days}d" }

Find duplicates by name

fddup() { fd -t f | sort | uniq -d }

  1. bat - Better cat

Basic Usage:

Syntax highlighted output

bat file.py

Show line numbers

bat -n file.py

Show all non-printable chars

bat -A file.py

Multiple files

bat file1.py file2.py

Plain output (no decorations)

bat -p file.py

Specific language

bat -l json data.txt

Diff two files

bat --diff file1 file2

bat Configuration:

Add to ~/.bashrc or ~/.zshrc

Set bat as default pager

export MANPAGER="sh -c 'col -bx | bat -l man -p'" export PAGER="bat"

Bat theme

export BAT_THEME="TwoDark"

Bat style

export BAT_STYLE="numbers,changes,header"

bat Aliases:

Replace cat with bat

alias cat='bat --paging=never'

Preview alias for fzf

alias preview='fzf --preview "bat --color=always {}"'

Pretty print JSON

alias json='bat -l json'

Pretty print YAML

alias yaml='bat -l yaml'

Diff with bat

alias diff='bat --diff'

  1. exa/eza - Better ls

Basic Usage:

Basic list

exa

Long format

exa -l

All files including hidden

exa -la

Tree view

exa --tree exa --tree --level=2

Sort by modified

exa -l --sort=modified

With git status

exa -l --git

Group directories first

exa -l --group-directories-first

Icons

exa -l --icons

exa Aliases:

Add to ~/.bashrc or ~/.zshrc

Replace ls with exa

alias ls='exa --group-directories-first' alias ll='exa -l --group-directories-first --git' alias la='exa -la --group-directories-first --git' alias lt='exa --tree --level=2' alias lta='exa --tree --level=2 -a'

With icons (if supported)

alias li='exa -l --icons --group-directories-first --git'

  1. zoxide - Smart cd

Basic Usage:

Initialize (add to shell rc)

eval "$(zoxide init bash)" # or zsh

Use z instead of cd

z projects # Jump to most frequent/recent match z pro # Partial match

Interactive selection

zi # Opens fzf for selection

Add directory manually

zoxide add /path/to/dir

Query database

zoxide query projects zoxide query -l # List all entries

zoxide Configuration:

Add to ~/.bashrc or ~/.zshrc

Initialize zoxide

eval "$(zoxide init bash --cmd cd)" # Replace cd

Or use custom command

eval "$(zoxide init bash --cmd j)" # Use 'j' for jump

  1. Shell Aliases and Functions

Essential Aliases:

Navigation

alias ..='cd ..' alias ...='cd ../..' alias ....='cd ../../..' alias ~='cd ~' alias -- -='cd -'

Safety

alias rm='rm -i' alias mv='mv -i' alias cp='cp -i'

Shortcuts

alias c='clear' alias h='history' alias q='exit' alias v='vim' alias e='${EDITOR:-vim}'

Git shortcuts

alias g='git' alias gs='git status' alias ga='git add' alias gc='git commit' alias gp='git push' alias gl='git log --oneline -20' alias gd='git diff' alias gb='git branch' alias gco='git checkout'

Docker shortcuts

alias d='docker' alias dc='docker compose' alias dps='docker ps' alias dimg='docker images' alias dlog='docker logs -f'

Common directories

alias proj='cd ~/projects' alias docs='cd ~/Documents' alias dl='cd ~/Downloads'

Utility Functions:

Create directory and cd into it

mkcd() { mkdir -p "$1" && cd "$1" }

Extract any archive

extract() { if [[ -f "$1" ]]; then case "$1" in *.tar.bz2) tar xjf "$1" ;; *.tar.gz) tar xzf "$1" ;; *.tar.xz) tar xJf "$1" ;; *.bz2) bunzip2 "$1" ;; *.rar) unrar x "$1" ;; *.gz) gunzip "$1" ;; *.tar) tar xf "$1" ;; *.tbz2) tar xjf "$1" ;; *.tgz) tar xzf "$1" ;; *.zip) unzip "$1" ;; *.Z) uncompress "$1" ;; *.7z) 7z x "$1" ;; *) echo "'$1' cannot be extracted" ;; esac else echo "'$1' is not a valid file" fi }

Get public IP

myip() { curl -s https://ifconfig.me }

Weather

weather() { curl -s "wttr.in/${1:-}" }

Quick note

note() { local notes_dir="${NOTES_DIR:-$HOME/notes}" local date=$(date +%Y-%m-%d) mkdir -p "$notes_dir" ${EDITOR:-vim} "$notes_dir/$date.md" }

Serve current directory

serve() { local port="${1:-8000}" python -m http.server "$port" }

Show disk usage for directory

duh() { du -h "${1:-.}" | sort -h | tail -20 }

Find process by name

psg() { ps aux | grep -v grep | grep -i "$1" }

Integration Examples

  1. Complete Shell Configuration

~/.bashrc or ~/.zshrc:

═══════════════════════════════════════════════════════════════

CLI Productivity Configuration

═══════════════════════════════════════════════════════════════

─────────────────────────────────────────────────────────────────

Environment

─────────────────────────────────────────────────────────────────

export EDITOR="vim" export VISUAL="$EDITOR" export PAGER="bat" export MANPAGER="sh -c 'col -bx | bat -l man -p'"

XDG Base Directory

export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" export XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}" export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"

─────────────────────────────────────────────────────────────────

History

─────────────────────────────────────────────────────────────────

HISTSIZE=50000 HISTFILESIZE=50000 HISTCONTROL=ignoreboth:erasedups shopt -s histappend

─────────────────────────────────────────────────────────────────

fzf Configuration

─────────────────────────────────────────────────────────────────

export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git' export FZF_DEFAULT_OPTS=' --height 40% --layout=reverse --border --preview-window=right:50%:wrap ' export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND" export FZF_CTRL_T_OPTS='--preview "bat --color=always --style=numbers --line-range=:500 {}"' export FZF_ALT_C_COMMAND='fd --type d --hidden --follow --exclude .git' export FZF_ALT_C_OPTS='--preview "exa --tree --level=2 --color=always {}"'

─────────────────────────────────────────────────────────────────

Tool Initialization

─────────────────────────────────────────────────────────────────

fzf keybindings

[ -f ~/.fzf.bash ] && source ~/.fzf.bash

zoxide

eval "$(zoxide init bash)"

starship prompt

eval "$(starship init bash)"

─────────────────────────────────────────────────────────────────

Aliases

─────────────────────────────────────────────────────────────────

Modern replacements

alias ls='exa --group-directories-first' alias ll='exa -l --group-directories-first --git' alias la='exa -la --group-directories-first --git' alias lt='exa --tree --level=2' alias cat='bat --paging=never' alias grep='rg' alias find='fd'

Navigation

alias ..='cd ..' alias ...='cd ../..' alias ....='cd ../../..'

Git

alias g='git' alias gs='git status' alias ga='git add' alias gc='git commit' alias gp='git push' alias gl='git log --oneline -20' alias gd='git diff'

Docker

alias d='docker' alias dc='docker compose' alias dps='docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"'

─────────────────────────────────────────────────────────────────

Functions

─────────────────────────────────────────────────────────────────

Fuzzy edit

fe() { local file file=$(fzf --preview 'bat --color=always --style=numbers --line-range=:500 {}') [[ -n "$file" ]] && ${EDITOR:-vim} "$file" }

Fuzzy cd

fcd() { local dir dir=$(fd --type d | fzf --preview 'exa --tree --level=2 --color=always {}') [[ -n "$dir" ]] && cd "$dir" }

Search and edit

rge() { local selection selection=$(rg --color=always --line-number "$1" | fzf --ansi) if [[ -n "$selection" ]]; then local file=$(echo "$selection" | cut -d: -f1) local line=$(echo "$selection" | cut -d: -f2) ${EDITOR:-vim} "+$line" "$file" fi }

Create and cd

mkcd() { mkdir -p "$1" && cd "$1" }

  1. Data Processing Pipeline

Process JSON API response

curl -s 'https://api.github.com/users/torvalds/repos?per_page=100'
| jq '.[] | {name: .name, stars: .stargazers_count}'
| jq -s 'sort_by(.stars) | reverse | .[0:10]'

Find large log files and show preview

fd -e log -S +10M
| fzf --preview 'tail -100 {}'
| xargs -I{} bat --line-range=:50 {}

Search code, preview matches, edit selected

rg --color=always -l "TODO"
| fzf --preview 'rg --color=always -C 3 "TODO" {}'
| xargs -o ${EDITOR:-vim}

Git log with diff preview

git log --oneline --color=always
| fzf --ansi --preview 'git show --color=always {1}'
| awk '{print $1}'
| xargs git show

  1. Interactive Script Template

#!/bin/bash

ABOUTME: Interactive CLI script using fzf and modern tools

ABOUTME: Template for building interactive shell tools

set -e

Colors

RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' NC='\033[0m'

log_info() { echo -e "${GREEN}[INFO]${NC} $"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $"; } log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; }

Check dependencies

check_deps() { local missing=() for cmd in fzf rg fd bat jq; do command -v "$cmd" >/dev/null || missing+=("$cmd") done

if [[ ${#missing[@]} -gt 0 ]]; then
    log_error "Missing dependencies: ${missing[*]}"
    exit 1
fi

}

Main menu using fzf

main_menu() { local options=( "Search files" "Search content" "Edit config" "Run tests" "Exit" )

local selection
selection=$(printf '%s\n' "${options[@]}" | fzf --header="Select action:")

case "$selection" in
    "Search files") search_files ;;
    "Search content") search_content ;;
    "Edit config") edit_config ;;
    "Run tests") run_tests ;;
    "Exit") exit 0 ;;
esac

}

search_files() { local file file=$(fd --type f | fzf --preview 'bat --color=always {}') [[ -n "$file" ]] && ${EDITOR:-vim} "$file" }

search_content() { local query read -p "Search pattern: " query rge "$query" }

edit_config() { local configs=("/.bashrc" "/.vimrc" "~/.gitconfig") local config config=$(printf '%s\n' "${configs[@]}" | fzf --header="Select config:") [[ -n "$config" ]] && ${EDITOR:-vim} "${config/#~/$HOME}" }

run_tests() { log_info "Running tests..." # Add test command here }

Main

check_deps while true; do main_menu done

Best Practices

  1. Tool Selection Guidelines

Task Tool Why

Find files by name fd Fast, intuitive syntax

Find files by content rg Faster than grep, better defaults

View files bat Syntax highlighting, line numbers

List files exa Icons, git status, tree view

Navigate directories zoxide Learns your patterns

Interactive selection fzf Fuzzy matching, preview

Process JSON jq Powerful, composable

  1. Performance Tips

Use fd instead of find

fd "pattern" # Instead of: find . -name "pattern"

Use rg instead of grep

rg "pattern" # Instead of: grep -r "pattern" .

Limit search depth

fd --max-depth 3 rg --max-depth 3

Exclude directories

fd -E node_modules -E .git rg --glob '!node_modules'

  1. Shell Startup Optimization

Lazy load slow tools

nvm() { unset -f nvm [ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh" nvm "$@" }

Cache expensive operations

_update_ps1_cache() { PS1_CACHE="$(expensive_command)" }

Troubleshooting

Common Issues

fzf not finding files:

Check FZF_DEFAULT_COMMAND

echo $FZF_DEFAULT_COMMAND

Test fd directly

fd --type f

Check for hidden files

fd -H

Colors not working:

Check terminal capabilities

echo $TERM

Force color output

export CLICOLOR_FORCE=1

Slow shell startup:

Profile startup time

time bash -i -c exit

Identify slow sources

for f in ~/.bashrc ~/.bash_profile; do echo "--- $f ---" time source "$f" done

zoxide not working:

Check initialization

type z

Rebuild database

zoxide import --from=z

Version History

  • 1.0.0 (2026-01-17): Initial release

  • Core CLI tools coverage (jq, fzf, ripgrep, fd, bat, exa)

  • Shell aliases and functions

  • Pipeline patterns

  • Integration examples

  • Shell configuration templates

Use this skill to build efficient, productive terminal workflows with modern CLI tools!

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

python-scientific-computing

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

vscode-extensions

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

github-actions

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

github-project-board

No summary provided by upstream source.

Repository SourceNeeds Review