How to get the second last argument from shell script?

10,986

Solution 1

set -- "first argument" "second argument" \
       "third argument" "fourth argument" \
       "fifth argument"
second_to_last="${@:(-2):1}"
echo "$second_to_last"

Note the quoting, which ensures that arguments with whitespace stick together -- which your original solution doesn't do.

Solution 2

In bash/ksh/zsh you can simply ${@: -2:1}

$ set a b c d 
$ echo ${@: -1:1}
c

In POSIX sh you can use eval:

$ set a b c d 
$ echo $(eval "echo \$$(($#-2))")
c

Solution 3

n=$(($#-1))
second_to_last=${!n}
echo "$second_to_last"

Solution 4

There are some options for all bash versions:

$ set -- aa bb cc dd ee ff
$ echo "${@: -2:1}   ${@:(-2):1}   ${@:(~1):1}   ${@:~1:1}   ${@:$#-1:1}"
ee   ee   ee   ee   ee

The (~) is the bitwise negation operator (search in the ARITHMETIC EVALUATION section).
It means flip all bits.

The selection even could be done with (integer) variables:

$ a=1  ; b=-a; echo "${@:b-1:1}   ${@:(b-1):1}   ${@:(~a):1}   ${@:~a:1}   ${@:$#-a:1}"
ee   ee   ee   ee   ee

$ a=2  ; b=-a; echo "${@:b-1:1}   ${@:(b-1):1}   ${@:(~a):1}   ${@:~a:1}   ${@:$#-a:1}"
dd   dd   dd   dd   dd

For really old shells, you must use eval:

eval "printf \"%s\n\" \"\$$(($#-1))\""
Share:
10,986
Niek de Klein
Author by

Niek de Klein

Updated on June 05, 2022

Comments

  • Niek de Klein
    Niek de Klein about 2 years

    I want to get the second last item given to a shell program. Currently I do it like this:

    file1_tmp="${@: -2}"
    oldIFS=$IFS
    IFS=" "
    count=0
    for value in $file1; do
      if [[ count -e 0 ]]; then
        file1=$value
      fi
        count=1
    done
    oldIFS=$IFS 
    

    I'm sure that there is a much easier way to do this. So how can I get the second last argument from a shell script input in as few lines as possible?