Bash – How to convert a String into Array in shell script

arraybashshell-script

I already read How to split a string into an array in bash but the question seems a little different to me so I'll ask using my data.

I have this line comming from STDIN :

(5,[a,b,c,d,e,f,g,h,i,j])

The five is my group ID and the letters are values of an array (the group data).
I need to get the group ID into a var and the letters into something I can work using IFS=',' read -r -a array <<< "$tline"

Best Answer

bkpIFS="$IFS"

IFS=',()][' read -r -a array <<<"(5,[a,b,c,d,e,f,g,h,i,j])"
echo ${array[@]}    ##Or printf "%s\n" ${array[@]}
5 a b c d e f g h i j

IFS="$bkpIFS"

Explanations:

  • First we are taking backup of default/current shell IFS with bkpIFS="$IFS";
  • Then we set IFS to set of delimiters ,, (, ), ] and [ with IFS=',()][' which means our input string can be delimited with one-or-more of these delimiters.

  • Next read -r -a array reads and split the line into an array called array only based on defined IFS above from input string passed in Here-String method. The -r option is used to tell read command don't does expansion on back-slash \ if come in input.

    IFS=',()][' read -a array <<<"(5,[a,b,c,d,e,f,g,h,i,j,\,k])"
    echo ${array[@]}
    5 a b c d e f g h i j ,k
    

    see the last ,k which it caused by having back-slash in input and read without its -r option.

  • With echo ${array[@]} we are printing all elements of array. see What is the difference between $* and $@? and Gilles's answer about ${array[@]} there with more details.

  • With printf "%s\n" ${array[@]} also there is other approach to printing array elements.

  • Now you can print a specific element of array with printf "%s\n" ${array[INDEX]} or same with echo ${array[INDEX]}.

  • Ah, sorry, forgot to give IFS back to shell, IFS="$bkpIFS" : )

Or using awk and its split function.

awk '{split($0,arr,/[][,)(]/)} 
    END{for (x in arr) printf ("%s ",arr[x]);printf "\n"}' <<<"(5,[a,b,c,d,e,f,g,h,i,j])"

Explanations:

  • Same here, we are splitting the entire line of input based on defined group of delimiters [...] in regexp constant /[...]/ which support in modern implementation of awk using split function. read more in section of split() function.

  • Next at the END{for (x in arr) printf ("%s ",arr[x]); ...} we are looping over array called arr and print their corresponding value. x here point to the index of array arr elements. read more about awk's BEGIN/END rules.

Side-redirect to How to add/remove an element to the array in bash?.

Related Question