gator
gator

Reputation: 3523

Is it possible to substitute a string inside a variable name?

I have three arrays like so:

bp_hl_test=("HL05" "HL10" "HL15")
bp_lr_test=("LR001" "LR010" "LR100")
bp_mr_test=("MR001" "MR010" "MR100")

For sake of example, I want to remove directories where the above arrays are subdirectories:

- results
-- bp
--- hl
---- HL05
---- HL10
---- HL15
---- HL20
--- lr
---- LR001
---- LR010
---- LR100
--- mr
---- MR001
---- MR010
---- MR100

Some code I'm using is below:

for i in "${bp_hl_test[@]}"; do
  rm -rf ../results/bp/hl/${i}
done
for i in "${bp_lr_test[@]}"; do
  rm -rf ../results/bp/lr/${i}
done
for i in "${bp_mr_test[@]}"; do
  rm -rf ../results/bp/mr/${i}
done

This does what I want, but I wonder if I can shorten this and reuse one bit of code more times.

bp_test={"hl" "lr" "mr")
bp_hl_test=("HL05" "HL10" "HL15")
bp_lr_test=("LR001" "LR010" "LR100")
bp_mr_test=("MR001" "MR010" "MR100")

for j in "${bp_test[@]}"; do
  for i in "${bp_${j}_test[@]}"; do
    rm -rf ../results/bp/${j}/${i}
  done
done

This doesn't work as I cannot, as far as I can tell, substitute inside a variable name like this. Is there a method to do this?

I have looked at the tagged question and it gives me bad substitution error:

for j in "${bp_test[@]}"; do
  for i in "${bp_${!j}_test[@]}"; do
    rm -rf ../results/bp/${j}/${i}
  done
done

Upvotes: 0

Views: 48

Answers (2)

tshiono
tshiono

Reputation: 22022

Would you please try the following with the -n option to declare:

bp_test=("hl" "lr" "mr")
bp_hl_test=("HL05" "HL10" "HL15")
bp_lr_test=("LR001" "LR010" "LR100")
bp_mr_test=("MR001" "MR010" "MR100")

for j in "${bp_test[@]}"; do
    declare -n ary="bp_${j}_test"
    for i in "${ary[@]}"; do
        echo rm -rf -- ../results/bp/"${j}/${i}"
    done
done

If it looks good, drop the echo.

Upvotes: 2

Walter A
Walter A

Reputation: 20002

You can hack the array in a temporary array.

for j in "${bp_test[@]}"; do
   a=( $(set | sed -rn '/^bp_'"${j}"'_test=/ s/[^"]*"([^"]*")/"\1 /gp'| sed 's/)$//') )
   for i in "${a[@]}"; do
       echo rm -rf ../results/bp/${j}/${i}
   done
done

Upvotes: 0

Related Questions