Process positional parameters non-destructively in Bash
Extract positional parameters without modifying (the number of) command line arguments ($# and $@).
# See: # - http://tldp.org/LDP/abs/html/string-manipulation.html#AEN5117 # - http://tldp.org/LDP/abs/html/internalvariables.html#POSPARAMREF # - http://tldp.org/LDP/abs/html/internalvariables.html#IFSREF # - http://tldp.org/LDP/abs/html/parameter-substitution.html#PARAMSUBREF # - cmdparser, http://codesnippets.joyent.com/posts/show/1697 export IFS=$' \t\n' # create a fake command line set -- "First one" "second" "third:one" "" "Fifth: :one" set -- "First one" "second" "third:"$'\n'"one" "" "Fifth: :one" echo $# # number of arguments printf "%s\n" "${@}" # all arguments printf "%s\n" "${1}" # first argument printf "%s\n" "${3}" # third argument printf "%s\n" "${5}" # last argument printf "%s\n" "${@:1}" # all arguments starting with the first printf "%s\n" "${@:2}" # all arguments starting with the second printf "%s\n" "${@:3}" # all arguments starting with the third printf "%s\n" "${@:(-$#):1}" # first argument printf "%s\n" "${@:$#:1}" # last argument printf "%s\n" "${!#}" # last argument printf "%s\n" "${@:1:1}" # first argument printf "%s\n" "${@:3:1}" # third argument printf "%s\n" "${@:5:1}" # fifth argument printf "%s\n" "${@:(-1):1}" # last argument printf "%s\n" "${@:(-2):1}" # second-to-last argument # process one positional parameter at a time without modifying $# or $@ for (( i=1; i <= $#; i++ )); do printf "%s\n" "${@:${i}:1}"; done echo $# # 5 # $# and $@ get modified for (( i=1; i <= $#; i++ )); do echo $i; printf "%s\n" "$1"; shift; done echo $# # 2 set -- "First one" "second" "third:"$'\n'"one" "" "Fifth: :one" # $# and $@ get modified while [[ $# -gt 0 ]]; do printf "%s\n" "$1"; shift; done echo $# # 0