Home > database >  Bash: combine parameter indirection with arithmetic expansion?
Bash: combine parameter indirection with arithmetic expansion?

Time:06-21

The script below prints positional parameters. The idea is to skip some optional arguments (where the number of optional args is given by SKIP), and then get the last two arguments. For the last arg, for example, I use an arithmetic expansion to get V2, and then indirect expansion of V2 to get A2. Running test a b c, for example, prints b and c.

Question: the two-step expansion is clunky. Is there a one-liner that will derive the value of a given arg?

#!/bin/bash

SKIP=1

# get second-from-last arg
V1=$(( SKIP 1 ))
A1=${!V1}

# get last arg
V2=$(( SKIP 2 ))
A2=${!V2}

echo A1 is $A1
echo A2 is $A2

CodePudding user response:

$@ and bash arrays could be what you're looking for:

$ cat foo
#!/usr/bin/env bash

declare -a args=( "$@" )
declare -i skip=1
for (( i = skip; i < ${#args[@]}; i   )); do
    printf '%d: %s\n' "$i" "${args[i]}"
done

$./foo b c d
1: b
2: c
3: d

CodePudding user response:

If you create an array from the positional parameters, you can use array indexing to get the desired values.

args=( "$@" )
echo "${args[-1]}"  # Last argument
echo "${args[-2]}"  # Next to last argument

echo "${args[4]}"  # Get the 5th argument (zero-based indexing)
echo ${args[SKIP 3]}  # If SKIP=1, same as above.

Array indices are evaluated in an arithmetic context, the same as if you used $((...)).

  •  Tags:  
  • bash
  • Related