1

Lets say I have the following file named "test"

which contains:

[a1b2c3]=test1.xyz
[d4e5f6]=test2.xyz
[g7h8i9]=test3.xyz
...

Which is about 30 lines long. I would want to assign

a1b2c3
d4e5f6
g7h8i9

into an array named array how would I do it?

with bash 3.1 this would be my attempt

declare -a array
while read -r line;
do
    array+=("$(echo "$line")")
done < test

But it seems that I need to upgrade my bash to 4 or 5 for declarative arrays. So the question would be, how do I separate specifically get the values inside the brackets per line to be assigned as different elements in an array array

This array values would be used in a curl script which should produce a file with the name of the values associated with it.

for i in "${array[@]}"
    do
    curl -X GET "https://api.cloudflare.com/client/v4/zones/$i/dns_records?" \
        -H "X-Auth-Email: $X-Auth-Email" \
        -H "X-Auth-Key: X-Auth-Key" \
        -H "Content-Type: application/json" \
        -o "${array[@]}.txt"
    done

so the expectation is that curl -X GET "https://api.cloudflare.com/client/v4/zones/a1b2c3/dns_records? would be run and an output file named test1.xyz.txt would be produced containing the dns records of the said link. Which goes for the next line and test2.xyz.txt and so on and so forth.

4
  • If you upgrade your bash you can use associative arrays (declare -A array). And then, if you dare using eval: eval "declare -A array=($(<test))". After which you can access the keys with ${!array[@]} and the values with ${array[@]}. Commented Mar 10, 2022 at 6:55
  • The eval helps in parsing the values into the array, however it seems I can only access the arrays with ${array[@]} but if I try testing getting an element with ${array[3]} it comes out empty. Commented Mar 10, 2022 at 7:35
  • What version of bash do you use? Did you pay attention to the upper case A in declare -A array? Did you pay attention to the ! in ${!array[@]}? Commented Mar 10, 2022 at 7:55
  • (1) There is no such thing like a declarative array in bash. You can have indexed arrays, and you can have associative arrays. (2) You say that you want to input into your array only the parts within the brackets, but you are storing the complete line. Please clarify how the content of your array is supposed to look like. Commented Mar 10, 2022 at 8:02

1 Answer 1

1

Assuming the string inside the brackets is composed of alphanumeric characters, would you please try:

#!/bin/bash

while IFS== read -r name val; do
    name=${name#[}                      # remove left square bracket
    name=${name%]}                      # remove right square bracket
    printf -v "var_$name" %s "$val"     # assign e.g. var_a1b2c3 to test1.xyz
done < test

for var in "${!var_@}"; do
    name=${var#var_}                    # retrieve e.g. a1b2c3 by removing var_
    curl -X GET "https://api.cloudflare.com/client/v4/zones/$name/dns_records?" \
    -H "X-Auth-Email: $X-Auth-Email" \
    -H "X-Auth-Key: X-Auth-Key" \
    -H "Content-Type: application/json" \
    -o "${!var}.txt"
done
  • As an indirect variable assignment, printf -v varname value works.
  • As an indirect variable referencing, "${!var_@}" is expanded to a list of variable names which starts with var_.
  • ${!var} refers to the value whose variable name is expressed by "$var".

Tested with bash-3.2.57. Hope it will be interoperable with bash-3.1.

Sign up to request clarification or add additional context in comments.

5 Comments

This is quite close! However the output file that gets created is this {"success":false,"errors":[{"code":7003,"message":"Could not route to \/zones\/var_a1b2c3\/dns_records, perhaps your object identifier is invalid?"},{"code":7000,"message":"No route for that URI"}],"messages":[],"result":null} which I assume that the value in the array was passed as var_a1b2c3. seems like it didn't remove the var_ in the elements when passed into the curl
Thank you for testing and finding the problem. It is exactly as you point out! Now I have fixed the code to remove var_ prefix from the variable name. Hope it will work now. BR.
Your edit actually fixed the whole problem! Thank you so much for the help! Marking this as the correct answer. A very clever way to circumvent with the issue on bash 3 that treats hexadecimal elements in the array starting with 0 as octal.
Thank you for the prompt feedback. Good to know it works. Would you please accept the answer by clicking the check mark besides the answer? Cheers.
Of course! Meant to do that just had to do a quick alt tab back to what I was working on. Thanks again for helping cheers!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.