parse quoted string in bash... just for fun
This commit is contained in:
parent
0426760211
commit
bca5333171
|
@ -0,0 +1,71 @@
|
|||
set -u
|
||||
set -e
|
||||
|
||||
# ParseArgs will parse a string that contains quoted strings the same as bash does
|
||||
# (same as most other *nix shells do). This is secure in the sense that it doesn't do any
|
||||
# executing or interpeting. However, it also doesn't do any escaping, so you shouldn't pass
|
||||
# these strings to shells without escaping them.
|
||||
parseargs() {
|
||||
notquote="-"
|
||||
str=$1
|
||||
declare -a m=()
|
||||
s=""
|
||||
|
||||
# Strip leading space, then trailing space, then add a terminating space.
|
||||
str="${str## }"
|
||||
str="${str%% }"
|
||||
str+=" "
|
||||
|
||||
last_quote="${notquote}"
|
||||
is_space=""
|
||||
n=$(( ${#str} - 1 ))
|
||||
i=-1
|
||||
for ((i=0;i<=$n;i+=1)); do
|
||||
c="${str:$i:1}"
|
||||
|
||||
# If we're ending a quote, break out and skip this character
|
||||
if [ "$c" == "$last_quote" ]; then
|
||||
last_quote=$notquote
|
||||
continue
|
||||
fi
|
||||
|
||||
# If we're in a quote, count this character
|
||||
if [ "$last_quote" != "$notquote" ]; then
|
||||
s+=$c
|
||||
continue
|
||||
fi
|
||||
|
||||
# If we encounter a quote, enter it and skip this character
|
||||
if [ "$c" == "'" ] || [ "$c" == '"' ]; then
|
||||
is_space=""
|
||||
last_quote=$c
|
||||
continue
|
||||
fi
|
||||
|
||||
# If it's a space, store the string
|
||||
re="[[:space:]]+" # must be used as a var, not a literal
|
||||
if [[ $c =~ $re ]]; then
|
||||
if [ "0" == "$i" ] || [ -n "$is_space" ]; then
|
||||
echo continue $i $is_space
|
||||
continue
|
||||
fi
|
||||
is_space="true"
|
||||
m+=("$s")
|
||||
s=""
|
||||
continue
|
||||
fi
|
||||
|
||||
is_space=""
|
||||
s+="$c"
|
||||
done
|
||||
|
||||
if [ "$last_quote" != "$notquote" ]; then
|
||||
>&2 echo "error"
|
||||
return 1
|
||||
fi
|
||||
|
||||
for arg in "${m[@]}"; do
|
||||
echo "$arg"
|
||||
done
|
||||
return 0
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
# usage
|
||||
source ./parseargs.sh
|
||||
export -f parseargs
|
||||
IFS=$'\r\n' GLOBIGNORE='*' args=($(parseargs "foo 'bar baz' qux *"))
|
||||
echo '$@': "${args[@]}"
|
||||
for arg in "${args[@]}"; do
|
||||
echo "$arg"
|
||||
done
|
Loading…
Reference in New Issue