Skip to main content
added 235 characters in body
Source Link
user8017719
user8017719

Only for bashFrom oldest to newer solutions:

The most portable solution, even older sh (sinceworks with spaces and glob characters) (no loop, faster):

eval printf "'%s\n'" "\"\${$#}\""

Since version 2.01) of bash

$ set -- The quick brown fox jumps over the lazy dog

$ printf '%s\n'     "${!#}     ${@:(-1)} ${@: -1} ${@:~0} ${!#}"
dog     dog dog dog dog

For ksh, zsh and bash:

$ echoprintf '%s\n' "${@: -1}    ${@:~0}"     # the space beetwen `:`
                                          # and `-1` is a must.
dog   dog

And for "next to last":

$ echoprintf '%s\n' "${@:~1:1}"
lazy

ToUsing printf to workaround any issues with arguments that start with a dash (like -n) use printf:.

$ printf '%s\n' "${@:~0}"
dog

For all shells and for older sh (works with spaces and glob characters) is:

$ set -- The quick brown fox jumps over the lazy dog "the * last argument"

$ eval echoprintf "'%s\n'" "\"\${$#}\""
The last * argument

Or, if you want to set a last var:

$ eval last=\${$#}; echoprintf '%s\n' "$last"
The last * argument

And for "next to last":

$ eval echoprintf "'%s\n'" "\"\${$(($#-1))}\""
dog

Only for bash (since version 2.01)

$ set -- The quick brown fox jumps over the lazy dog

$ printf '%s\n'     "${!#}     ${@:(-1)} ${@: -1} ${@:~0} ${!#}"
dog     dog dog dog dog

For ksh, zsh and bash:

$ echo "${@: -1}    ${@:~0}"     # the space beetwen `:` and `-1` is a must.
dog   dog

And for "next to last":

$ echo "${@:~1:1}"
lazy

To workaround any issues with arguments that start with a dash (like -n) use printf:

$ printf '%s\n' "${@:~0}"
dog

For all shells and for older sh (works with spaces and glob characters) is:

$ set -- The quick brown fox jumps over the lazy dog "the * last argument"

$ eval echo "\"\${$#}\""
The last * argument

Or, if you want to set a last var:

$ eval last=\${$#}; echo "$last"
The last * argument

And for "next to last":

$ eval echo "\"\${$(($#-1))}\""
dog

From oldest to newer solutions:

The most portable solution, even older sh (works with spaces and glob characters) (no loop, faster):

eval printf "'%s\n'" "\"\${$#}\""

Since version 2.01 of bash

$ set -- The quick brown fox jumps over the lazy dog

$ printf '%s\n'     "${!#}     ${@:(-1)} ${@: -1} ${@:~0} ${!#}"
dog     dog dog dog dog

For ksh, zsh and bash:

$ printf '%s\n' "${@: -1}    ${@:~0}"     # the space beetwen `:`
                                          # and `-1` is a must.
dog   dog

And for "next to last":

$ printf '%s\n' "${@:~1:1}"
lazy

Using printf to workaround any issues with arguments that start with a dash (like -n).

For all shells and for older sh (works with spaces and glob characters) is:

$ set -- The quick brown fox jumps over the lazy dog "the * last argument"

$ eval printf "'%s\n'" "\"\${$#}\""
The last * argument

Or, if you want to set a last var:

$ eval last=\${$#}; printf '%s\n' "$last"
The last * argument

And for "next to last":

$ eval printf "'%s\n'" "\"\${$(($#-1))}\""
dog
Added indirect expansion `${!#}`.
Source Link
user8017719
user8017719

For ksh, zsh andOnly for bash: (since version 2.01)

$ set -- The quick brown fox jumps over the lazy dog

$ printf '%s\n'     "${!#}     ${@:(-1)} ${@: -1} ${@:~0} ${!#}"
dog     dog dog dog dog

For ksh, zsh and bash:

$ echo "${@: -1}    ${@:~0}"     # the space beetwen `:` and `-1` is a must.
dog   dog

And for "next to last":

$ echo "${@:~1:1}"
lazy

To workaround any issues with arguments that start with a dash (like -n) use printf:

$ printf '%s\n' "${@:~0}"
dog

And the correct way to deal with spacesFor all shells and glob characters infor older sh (works with spaces and glob characters) is:

$ set -- The quick brown fox jumps over the lazy dog "the * last argument"

$ eval echo "\"\${$#}\""
The last * argument

Or, if you want to set a last var:

$ eval last=\${$#}; echo "$last"
The last * argument

And for "next to last":

$ eval echo "\"\${$(($#-1))}\""
dog

For ksh, zsh and bash:

$ set -- The quick brown fox jumps over the lazy dog

$ echo "${@:~0}"
dog

And for "next to last":

$ echo "${@:~1:1}"
lazy

To workaround any issues with arguments that start with a dash (like -n) use:

$ printf '%s\n' "${@:~0}"
dog

And the correct way to deal with spaces and glob characters in sh is:

$ set -- The quick brown fox jumps over the lazy dog "the * last argument"

$ eval echo "\"\${$#}\""
The last * argument

Or, if you want to set a last var:

$ eval last=\${$#}; echo "$last"
The last * argument

And for "next to last":

$ eval echo "\"\${$(($#-1))}\""
dog

Only for bash (since version 2.01)

$ set -- The quick brown fox jumps over the lazy dog

$ printf '%s\n'     "${!#}     ${@:(-1)} ${@: -1} ${@:~0} ${!#}"
dog     dog dog dog dog

For ksh, zsh and bash:

$ echo "${@: -1}    ${@:~0}"     # the space beetwen `:` and `-1` is a must.
dog   dog

And for "next to last":

$ echo "${@:~1:1}"
lazy

To workaround any issues with arguments that start with a dash (like -n) use printf:

$ printf '%s\n' "${@:~0}"
dog

For all shells and for older sh (works with spaces and glob characters) is:

$ set -- The quick brown fox jumps over the lazy dog "the * last argument"

$ eval echo "\"\${$#}\""
The last * argument

Or, if you want to set a last var:

$ eval last=\${$#}; echo "$last"
The last * argument

And for "next to last":

$ eval echo "\"\${$(($#-1))}\""
dog
Source Link
user8017719
user8017719

For ksh, zsh and bash:

$ set -- The quick brown fox jumps over the lazy dog

$ echo "${@:~0}"
dog

And for "next to last":

$ echo "${@:~1:1}"
lazy

To workaround any issues with arguments that start with a dash (like -n) use:

$ printf '%s\n' "${@:~0}"
dog

And the correct way to deal with spaces and glob characters in sh is:

$ set -- The quick brown fox jumps over the lazy dog "the * last argument"

$ eval echo "\"\${$#}\""
The last * argument

Or, if you want to set a last var:

$ eval last=\${$#}; echo "$last"
The last * argument

And for "next to last":

$ eval echo "\"\${$(($#-1))}\""
dog