0

Say I have a string of

samp_str="ABCDEF"

I want to split them up into chars like

var1=A
var2=B
var3=C
var4=D
var5=E
var6=F

How can I do that?

poh
  • 1
  • 1
  • 4

4 Answers4

2

About the only way I can think of to associate and store each character with a reference like var0, var1, ... in bash > 4 would be with the use of an associative array. If you just want to print the value next to a label var0, var1, ..., then you don't need to worry about storing anything, just split var into characters and echo a label next to each character.

If you don't care to give the individual characters any type of name, then a normal indexed array as Darby_Crash provided an example of in his answer is fine. It's actually less effort, but indexes will be all you have available.

However, if your intent is to be able to store the individual characters for later use, and then use a name to reference the characters later on, that's what an associative array is intended to provide.

For example, you can declare and associative array with declare -A varname. You can then use a key like the string made up of var# to store the character (e.g. varname[var#]=char). You can then later reference each character by providing the var# is the key (index) in normal array syntax to retrieve the character (e.g. echo "var#=${varname[var#]}". In your case something like:

declare -A a                            ## declare associative array
var="ABCDEF"
for ((i = 0; i < ${#var}-1; i++)); do   ## loop over each char
a[var$i]=${var:i:1}                     ## assign under index 'var$i'
done

## output values saved in a
for ((i = 0; i < ${#var}; i++)); do
    echo "var$i=${a[var$i]}"
done

Example Use/Output

$ (
>     declare -A a                            ## declare associative array
>     var="ABCDEF"
>     for ((i = 0; i < ${#var}; i++)); do     ## loop over each char
>     a[var$i]=${var:i:1}                     ## assign under index 'var$i'
>     done
>
>     ## output values saved in a
>     for ((i = 0; i < ${#var}; i++)); do
>         echo "var$i=${a[var$i]}"
>     done
> )
var0=A
var1=B
var2=C
var3=D
var4=E
var5=F

note: while you can iterate over an associative array using for key in ${!varname[@]}; do, that will not preserve any type of sort-order (associative arrays are unsorted). Above, since your references are made of of var#, simply looping over each # and using a derived key can preserve sort order. Granted, the benefit over an indexed array in doing it this way is obviously minimal.

Look over all answers and let me know if you have any questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Solid solution....@poh does that answer your question? if so, it's nice to bother and accept :) – z atef Oct 28 '17 at 15:51
0

This is my solution

string='ABCDEF'
for ((i=1;i<=${#string};i++)); do eval "var$i=\"${string:$((i-1)):1}\""; done

Output

darby@Debian:~/Scrivania$ echo $var1
A
darby@Debian:~/Scrivania$ echo $var2
B
darby@Debian:~/Scrivania$

or you can do it using array (is the better method)

string='ABCDEF'
for ((i=0;i<=${#string};i++)); do var[$i]="${string:i:1}"; done

Output

darby@Debian:~/Scrivania$ echo "${var[0]}"
A
darby@Debian:~/Scrivania$ echo "${var[1]}"
B
darby@Debian:~/Scrivania$
Darby_Crash
  • 446
  • 3
  • 6
  • Always worth dropping a note of caution about using `eval` sparingly when calling on a set of commands made up of variables. Like a bungled attempt to remove one directory that ends up deleting the entire root filesystem, (e.g.`var=; dir=$var/; command="sudo rm -r $dir"; eval $command`) very bad things can happen.... – David C. Rankin Oct 28 '17 at 06:03
  • You're right but in this specific case is the less bad. – Darby_Crash Oct 28 '17 at 06:08
  • Yes agreed. But you know how new users are that find a new toy. Pretty soon they are daisy chaining loops together to eval `:)` – David C. Rankin Oct 28 '17 at 06:20
0

Something like this should do it for you. You don't need to worry about the siz eof the string. It's calculated using this syntax ${#var},You will need to make the array ends at ${#var} - 1. lemme know if anything :)

 $ var="ABCDEF" ; for i in $(seq 0  $((${#var} - 1 )) ) ; do  echo var${i}=${var:${i}:1}  ; done 

Outputs the follwing:

echo var0=A
echo var1=B
echo var2=C
echo var3=D
echo var4=E
echo var5=F 
z atef
  • 7,138
  • 3
  • 55
  • 50
  • `$(seq 0 ${#var})` should be `$(seq 0 $((${#var} - 1)))`. bash array indexes are *zero* based (e.g. 6-char string has indexes `0-5`) Also, you are actually not storing anything for later reference. `"split them up"` is a bit ambiguous, but it appears he wants to assign to some storage for later use. – David C. Rankin Oct 28 '17 at 05:02
  • Thanks @DavidC.Rankin for your feedback - I have updated length to be $((${#var} - 1 )). if you noticed my answer it, it says : You will need to make the array ends at ${#var} - 1. – z atef Oct 28 '17 at 15:49
0

A other way

samp_str="ABCDEF"
var+=
while read -n 1 c; do
  var+=("$c")
done<<<$samp_str
unset var[-1]
unset var[0]
for i in ${!var[*]} ; do
  echo var[$i] = ${var[$i]}
done
ctac_
  • 2,413
  • 2
  • 7
  • 17