Skip to content

Instantly share code, notes, and snippets.

@chris-marsh
Last active February 3, 2016 21:48
Show Gist options
  • Save chris-marsh/cb0a99ab16e3966236a9 to your computer and use it in GitHub Desktop.
Save chris-marsh/cb0a99ab16e3966236a9 to your computer and use it in GitHub Desktop.
Shell script to take an argument list and expand any grouped short options. For example; -lotr becomes -l -o -t -r.Compatible with most shells. Tested on Bash, Dash and BusyBox.
#!/bin/bash
#
# Chris Marsh 2016
# Written for compatibility. Tested on Bash and BusyBox.
#
# -----------------------------------------------------------------------------
# Takes an argument list and expand any group short arguments into seperate
# options.
# Usage: eval "set -- $(split_opts "$@")"
# eval "set -- $(split_opts "-lotr -file /some/file.txt)"
# The first example passes the cli argument list which returns a split version.
# The second example would return '-l' '-o' '-t' '-r' '-f' '/some/file.txt'
split_opts() {
local args=""
for arg in "$@"; do
if [ "${#arg}" -gt 1 ] && [ "${arg:0:1}" = "-" ]; then
if [ "${arg:1:1}" = "-" ]; then
args="$args '$arg'";
else
for i in $(seq 1 ${#arg}); do
opt=${arg:$i:1}
if [ ${#opt} -gt 0 ]; then
args="$args '-$opt'";
fi
done;
fi
else
args="$args '$arg'";
fi
done
echo $args
}
eval "set -- $(split_opts "$@")"
while [[ $1 ]]; do
case "$1" in
'-l'|'--lord')
echo "'lord' (-l) was selected"
;;
'-o'|'--of')
echo "'of' (-o) was selected"
;;
'-t'|'--the')
echo "'The' (-t) was selected"
;;
'-r'|'--rings')
echo "'Rings' (-r) was selected"
;;
'-f'|'--file')
file=$2
shift
echo "'File' (-f) was selected and was ... $file"
;;
-*)
echo "Option '$1' is not valid.\nTry '$0 --help for more information."
;;
*)
echo "Extra option was used. This may be intended or an error: $1"
;;
esac
shift
done
@chris-marsh
Copy link
Author

Arguments with spaces, assuming passed into the app in quotes, are preserved.
No order is imposed on the arguments.
Options which take a second argument, eg (-f some_file.txt) will always use the next argument.
Eg
$ MyApp -rwf file.txt
Will work. -> -r -w -f file.text ... -f find 'file.txt'
$ MyApp -rfw file.txt
will not. -> -r -f -w file.text .... -f finds

$ ./split_opts.sh -r -f "/my/file thing.txt" --lord
'Rings' (-r) was selected
'File' (-f) was selected and was ... /my/file thing.txt
'lord' (-l) was selected

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment