Skip to content

Instantly share code, notes, and snippets.

@unstabler
Created May 4, 2026 20:00
Show Gist options
  • Select an option

  • Save unstabler/691e2c83a04e52d06fdc355c85b981c9 to your computer and use it in GitHub Desktop.

Select an option

Save unstabler/691e2c83a04e52d06fdc355c85b981c9 to your computer and use it in GitHub Desktop.
fzcd - fuzzy chdir
# fzcd - fuzzy chdir: find and print a subdirectory matching a suffix pattern
set -euo pipefail
show_usage() {
echo "Usage: fzcd [-a] <path-suffix>" >&2
echo " Find a subdirectory whose path ends with <path-suffix>." >&2
echo " -a Include hidden directories in search" >&2
exit 1
}
IGNORE_LIST=(
.git
.hg
.svn
.cache
node_modules
build
cmake-build-debug
cmake-build-release
)
include_all=false
while getopts "a" opt; do
case "$opt" in
a) include_all=true ;;
*) show_usage ;;
esac
done
shift $((OPTIND - 1))
[ $# -eq 0 ] && show_usage
pattern="$1"
# Strip trailing slash if present
pattern="${pattern%/}"
# Build find command with ignore list
if [ "$include_all" = true ]; then
results=$(find . -type d 2>/dev/null | sed 's|^\./||' | grep -E "(^|/)${pattern}$" || true)
else
prune_args=()
for name in "${IGNORE_LIST[@]}"; do
prune_args+=(-name "$name" -o)
done
# Also prune hidden directories not in the list
results=$(find . \( "${prune_args[@]}" -path '*/.*' \) -prune -o -type d -print 2>/dev/null | sed 's|^\./||' | grep -E "(^|/)${pattern}$" || true)
fi
# Filter out empty lines and the current directory
results=$(echo "$results" | sed '/^$/d' | grep -v '^.$' || true)
count=$(echo "$results" | sed '/^$/d' | wc -l | tr -d ' ')
if [ "$count" -eq 0 ] || [ -z "$results" ]; then
echo "fzcd: no directory matching '*/${pattern}'" >&2
exit 1
elif [ "$count" -eq 1 ]; then
echo "$results"
else
echo "=== CONFLICT! ===" >&2
i=1
while IFS= read -r line; do
echo "$i. $line" >&2
i=$((i + 1))
done <<< "$results"
echo "" >&2
printf "(1-%d) ? " "$count" >&2
read -r choice < /dev/tty
if ! [[ "$choice" =~ ^[0-9]+$ ]] || [ "$choice" -lt 1 ] || [ "$choice" -gt "$count" ]; then
echo "fzcd: invalid selection" >&2
exit 1
fi
echo "$results" | sed -n "${choice}p"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment