0

I have a bash function that reads a csv file and I want that function to return an array. How do I do that?

I know that typically bash does not "return objects" but I wonder if there's a hack so that the following code:

data=$(readFromCSV $file)

returns an array from the custom function readFromCSV. And I mean $data being a true array so I could for instance run

echo {#data[@]}

and it would tell me how many items are in the array.

how would you tell the function to return the array?

thanks

2

1 Answer 1

-1

so basically this is how I proceeded to imitate "an array object" to be passed from a csv file.

First, create the function for the csv:

function readFromCSV() {
    file=$1
    arr_csv=() 
    while IFS= read -r line 
    do
        arr_csv+=("$line")
    done < $file

    echo ${arr_csv[*]} # this will output a string
}

then call the function:

list=$(readFromCSV $file)

then remap the string to an array:

arrayCSV=($list)

now arrayCSV is an array of the values frome the CSV file.

Sign up to request clarification or add additional context in comments.

5 Comments

There's no point in defining the array inside the function. You'll get the exact same behavior if you just write each line to standard output: while IFS= read -r line; do echo "$line"; done < "$file".
Re: function funcName() {, see wiki.bash-hackers.org/scripting/obsolete -- this merges legacy ksh and POSIX syntax in a way that isn't compatible with either legacy ksh or POSIX.
...and as for the actual immediate question at hand, this is very broken code for no good reason. Bash 4.3 namerefs let you directly assign to a caller-named array from within a function. When you use echo ${arr_csv[*]}, you defeat the point of ever using an array in the first place, because you destroy the information about where element boundaries were originally stored.
To provide a concrete example, array=( "first element" "*" "third element" ) -- now when you string=$(echo ${array[*]}) and use newArray=( $string ), you get newArray[0]="first", newArray[1]="element", a list of filenames in the third element onward, etc; you've lost the information that first element was ever just one string, and that * was quoted.
@chepner, not the exact same behavior -- if one just echo'd a line at a time to stdout you could use readarray or mapfile to construct an array with correct boundaries on the outside, assuming no array elements contain literal newlines (not a 100% safe assumption, granted, being why NUL delimiters are better). What the OP is doing here is worse; their echo puts everything onto one line.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.