Search code examples
arraysstringbashsplitzsh

Simplest way to split a csv string into an array that works for both bash & zsh


What is the simplest way to split a csv string into an array using only builtins that works for both bash & zsh?

I have separate code that works for bash and for zsh, but I haven't yet found anything that works for both:

csv='a,b,c'

# Works in zsh, but not in bash
array=(${(s:,:)csv})

# Works in bash, but not in zsh
array=(${csv//,/ }) # This requires that $IFS contains the space character

Solution

  • As pointed out in the comments, there are two nearly identical commands, one for each shell.

    # bash
    IFS=, read -ra array <<< "$csv"
    
    # zsh
    IFS=, read -rA array <<< "$csv"
    

    The syntax is the same; the only difference is whether you use a or A as the option to read. I would recommend adding a conditional statement that detects which shell is executing the script, then use a variable to store the correct option.

    if [ -n "$BASH_VERSION" ]; then
        arr_opt=a
    elif [ -n "$ZSH_VERSION" ]; then
        arr_opt=A
    fi
    
    IFS=, read -r"$arr_opt" array <<< "$csv"
    

    Checking for non-empty version parameters isn't foolproof, but it should be good enough.