Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read tab-separated file line into array

Tags:

arrays

bash

I would like to read a file into a script, line by line. Each line in the file is multiple values separated by a tab, I'd like to read each line into an array.

Typical bash "read file by line" example;

while read line do echo $line; done < "myfile" 

For me though, myfile looks like this (tab separated values);

value1 value2 value3 value4 value5 value6 

On each iteration of the loop, I'd like each line to go into an array so I can

while read line into myArray do  echo myArray[0]  echo myArray[1]  echo myArray[2] done < "myfile" 

This would print the following on the first loop iteration;

value1 value2 value3 

Then on the second iteration it would print

value4 value5 value6 

Is this possible? The only way I can see is to write a small function to break out the values manually, is there built in support in bash for this?

like image 509
jwbensley Avatar asked Mar 16 '12 11:03

jwbensley


2 Answers

You're very close:

while IFS=$'\t' read -r -a myArray do  echo "${myArray[0]}"  echo "${myArray[1]}"  echo "${myArray[2]}" done < myfile 

(The -r tells read that \ isn't special in the input data; the -a myArray tells it to split the input-line into words and store the results in myArray; and the IFS=$'\t' tells it to use only tabs to split words, instead of the regular Bash default of also allowing spaces to split words as well. Note that this approach will treat one or more tabs as the delimiter, so if any field is blank, later fields will be "shifted" into earlier positions in the array. Is that O.K.?)

like image 132
ruakh Avatar answered Oct 01 '22 14:10

ruakh


If you really want to split every word (bash meaning) into a different array index completely changing the array in every while loop iteration, @ruakh's answer is the correct approach. But you can use the read property to split every read word into different variables column1, column2, column3 like in this code snippet

while IFS=$'\t' read -r column1 column2 column3 ; do   printf "%b\n" "column1<${column1}>"   printf "%b\n" "column2<${column2}>"   printf "%b\n" "column3<${column3}>" done < "myfile" 

to reach a similar result avoiding array index access and improving your code readability by using meaningful variable names (of course using columnN is not a good idea to do so).

like image 45
slylittl3 Avatar answered Oct 01 '22 12:10

slylittl3