Skip to content

Instantly share code, notes, and snippets.

@konsolebox
Last active June 20, 2023 09:22
Show Gist options
  • Save konsolebox/7c762b1ac0c54afa591a8691685bf235 to your computer and use it in GitHub Desktop.
Save konsolebox/7c762b1ac0c54afa591a8691685bf235 to your computer and use it in GitHub Desktop.
function dirname {
local names=() delim='\n' n x
local VERSION=0.1
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
echo "Usage: dirname [OPTIONS] [--] NAME ...
Removes the last non-slash component from NAME and the slashes that
follow it. The result is then further trimmed of remaining trailing
slashes. A resulting name that is empty evaluates to '/' or '.'
depending if the original name begins with a forward slash or not.
Options:
-z, --zero Use NUL as delimiter instead of a newline
-h, --help Show this usage info and exit
-v, --version Show version and exit"
;;
-v|--version)
echo "${VERSION}"
;;
-z|--zero)
delim='\0'
;;
--)
names+=("${@:2}")
break
;;
-[!-][!-]*)
set -- "${1:0:2}" "-${1:2}" "${@:2}"
continue
;;
-?*)
echo "dirname: Unrecognized option: $1" >&2
return 1
;;
*)
names+=("$1")
;;
esac
shift
done
if ! shopt -q extglob; then
echo "dirname: This function requires extglob enabled." >&2
return 1
fi
if [[ ${#names[@]} -eq 0 ]]; then
echo "dirname: No name specified." >&2
return 1
fi
for n in "${names[@]}"; do
x=${n%%+([^/])*(/)} x=${x%%+(/)}
if [[ -z $x ]]; then
[[ $n == /* ]] && x=/ || x=.
fi
printf "%s${delim}" "$x"
done
return 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment