Search code examples
arraysbashifs

Modify IFS in bash while building and array


I'm trying to build an array from 4 different arrays in bash with a custom IFS, can you lend me a hand please.

#!/bin/bash   
arr1=(1 2 3 4)
arr2=(1 2 3 4)  
arr3=(1 2 3 4)  
arr4=(1 2 3 4)
arr5=()
oldIFS=$IFS
IFS=\;
for i in ${!arr1[@]}; do  
    arr5+=($(echo ${arr1[i]} ${arr2[i]} ${arr3[i]} ${arr4[i]}))
done
IFS=$oldIFS
echo ${arr5[@]}

i what the output to be:

1 1 1 1;2 2 2 2;3 3 3 3;4 4 4 4 4 4

But it doesn't work the output is with normal ' '.

1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 4 4

Any ideeas?

I tried IFS in different places: 1) In the for loop 2) Before arr5()

I tested it in the for loop and after IFS does change to ";" but it doesn't take effect in the array creation.


Solution

  • IFS is used during the expansion of ${arr5[*]}, not while creating arr5.

    arr1=(1 2 3 4)
    arr2=(1 2 3 4)  
    arr3=(1 2 3 4)  
    arr4=(1 2 3 4)
    arr5=()
    for i in ${!arr1[@]}; do  
        arr5+=("${arr1[i]}" "${arr2[i]}" "${arr3[i]}" "${arr4[i]}")
    done
    (IFS=";"; echo "${arr5[*]}")
    

    Where possible, it's simpler to just change IFS in a subshell rather than try to save and restore its value manually. (Your attempt fails in the rare but possible case that IFS was unset to begin with.)

    That said, if you just want the ;-delimited string and arr5 was a way to get there, just build the string directly:

    for i in ${!arr1[@]}; do
      s+="${arr1[i]} ${arr2[i]} ${arr3[i]} ${arr4[i]};"
    done
    s=${s%;}  # Remove the last extraneous semicolon