0

I have an application that takes from 1 to 20 variables. The names of each of the variables are identical EXCEPT they end with a sequential number. From _1 to _20.

For example: Value_1, Value_2, Value_3...Value_20

What I'd like to do is:

  1. See if the variables exist first. There may be one variable or 20 of them. Furthermore, they are not guaranteed to be in a particular order. For example, only Value_15 might exist.
  2. For the variables beginning with Value_ I'd like to check and see if they are null or not.
  3. For those variables that are NOT NULL or EMPTY I want to get their values and feed them into another process.

I've heard using arrays might be the way to go. But I'd have to convert the variables found into an array...OR I could just interact over them from 1...20 and see if they exist and it they have values assigned to them, I could pull the value from each one.

What is the best way of doing this?

KSS
  • 821
  • 3
  • 10
  • 26
  • You can access all variable via `$@` and number of input variables using `$#`. For checking if variable is empty use `if [ -z "$VALUE_1" ]` – Digvijay S Jun 15 '20 at 04:58
  • Is the different case for `VALUE_1` vs `Value_2` and so forth intentional? – tink Jun 15 '20 at 05:07
  • 1
    See the non-array-based answers to ["Dynamic variable names in Bash"](https://stackoverflow.com/questions/16553089/dynamic-variable-names-in-bash), and also [BashFAQ #6](https://mywiki.wooledge.org/BashFAQ/006). – Gordon Davisson Jun 15 '20 at 05:10

1 Answers1

3

Bash provides for variable indirection using, e.g. var_$i (where $i is a number), you can assign the pattern created (e.g. tmp="var_$i") and then get the value from the resulting var_x name using ${!tmp}., e.g.

#!/bin/bash

var_1=1
var_2=2
var_4=4
var_5=5
var_6=6
var_8=8
var_9=9
var_10=10
var_11=11
var_13=13
var_14=14
var_15=15
var_16=16
var_18=18
var_19=19

for ((i = 1; i <= 20; i++)); do
    tmp="var_$i"
    if [ -n "${!tmp}" ]; then
        printf "var_%d exits: %s\n" "$i" "${!tmp}"
    fi
done

This has been incorporated into the nameref declaration in bash since 4.3. You have the option of declare -n tmp=var_x to declare a nameref, e.g.

for ((i = 1; i <= 20; i++)); do
    declare -n tmp="var_$i"
    if [ -n "$tmp" ]; then
        printf "var_%d exits: %s\n" "$i" "$tmp"
    fi
done

Give both a try and let me know if you have questions.

Example Use/Output

In both cases you will receive:

$ bash nameref.sh
var_1 exits: 1
var_2 exits: 2
var_4 exits: 4
var_5 exits: 5
var_6 exits: 6
var_8 exits: 8
var_9 exits: 9
var_10 exits: 10
var_11 exits: 11
var_13 exits: 13
var_14 exits: 14
var_15 exits: 15
var_16 exits: 16
var_18 exits: 18
var_19 exits: 19
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85