creating variables from data after using the fold command

60 views Asked by At

My main goal is to set up variables which are taken from a string which can be of various lengths. Each variable must contain 4 digits from the string (ie var_1 = digits 1-4, var_2 = digits 5-8 etc). By using the fold -w4 command I can get the string into blocks of 4. For example:

string = 1234567898765432
fold -w4:
1234
5678
9876
5432

Rather than manually create the variables by copying the data, can anyone suggest how I can get Bash to automatically create variables for each block of 4 that is created?

I have searched Google and even tried ChatGPT. The suggestion given doesn't seem to work:

# Get the length of the input string
    length=${#input_string}

# Loop through the string in steps of 4 characters
    for (( i=0; i<$length; i+=4 )); do
        # Extract 4 characters starting from position i
        substring="${input_string:i:4}"

        # Create a variable with the extracted substring
        var_name="var_$((i/4 + 1))"
        declare "$var_name=$substring"
    done

# Print the created variables
    echo "Created variables:"
    declare -p | grep -E '^declare -\w+ var_[0-9]+='

All that happens is I get the "Created variables" written to the terminal.

2

There are 2 answers

5
markp-fuso On

The normal approach would be to create an array of the entries, easily doable with mapfile (or readarray - a synonym of mapfile); in this case we'll also use process substitution to feed the fold results to mapfile, eg:

$ string=1234567898765432
$ mapfile -t arr < <(fold -w4 <<< "${string}")
$ typeset -p arr
declare -a arr=([0]="1234" [1]="5678" [2]="9876" [3]="5432")

The chatGPT answer is working it's just that the final line of the script (declare -p | grep -E ...) needs some tweaking. Alternatives for the last line:

$ declare -p | grep 'var_'
declare -- var_1="1234"
declare -- var_2="5678"
declare -- var_3="9876"
declare -- var_4="5432"
declare -- var_name="var_4"           # probably don't want to see this one

$ declare -p | grep '^declare -- var_[0-9]*='
declare -- var_1="1234"
declare -- var_2="5678"
declare -- var_3="9876"
declare -- var_4="5432"

$ declare -p | grep -E ' var_[0-9]+='
declare -- var_1="1234"
declare -- var_2="5678"
declare -- var_3="9876"
declare -- var_4="5432"
0
pjh On

This Shellcheck-clean pure Bash code demonstrates one way to populate an array with the 4-character blocks extracted from the input string:

#! /bin/bash -p

input_string=1234567898765432
blocks=()
for ((i=0; i<${#input_string}; i+=4)); do
    blocks+=( "${input_string:i:4}" )
done
declare -p blocks
  • This should work with any version of Bash since 2.0 (released in 1996).
  • It will work for input_string containing any possible characters (including spaces, newlines, and glob characters).