Let\'s say I have a text file \'demo.txt\' who has a table in it like this:
1 2 3
4 5 6
7 8 9
Now, I want to read each line separat
How can accesses each line separately and in that line get access to each member?
Per the Bash Reference Manual, Bash provides one-dimensional indexed and associative array variables. So you cannot expect matrix[1][2]
or similar to work. However, you can emulate matrix access using a bash associative arrays, where the key denotes a multiple dimension.
For example, matrix[1,2]
uses the string "1,2" as the associative array key denoting the 1st row, 2nd column. Combining this with readarray
:
typeset -A matrix
function load() {
declare -a a=( $2 )
for (( c=0; c < ${#a[@]}; c++ ))
do
matrix[$1,$c]=${a[$c]}
done
}
readarray -C load -c 1 <<< $'1 2 3\n4 5 6\n7 8 9'
declare -p matrix
To expand on Damien's answer (and because I can't submit comments yet...) you just iterate on read. What I mean is something like the following
exec 5<demo.txt
for i in `seq 1 ${numOfLinesInFile}`
do
read -a arr -u 5
for j in `seq 0 ${numOfColumnsMinus1}`
do
echo ${arr[$j]}
done
done
I hope you found a solution already (sorry to bump...). I stumbled upon this page while helping teach a friend and figured others may do the same.
Sorry to bump but I believe there's an easy and very clean solution for your request:
$ cat demo.txt
1 2 3
4 5 6
7 8 9
$ while read line;do IFS=' ' myarray+=(${line}); done < demo.txt
$ declare -p myarray
declare -a myarray='([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="7" [7]="8" [8]="9")'
$
This is the expected behavior. readarray
will create an array where each element of the array is a line in the input.
If you want to see the whole array you need to use
echo "${myarray[@]}"
as echo "$myarray
will only output myarray[0]
, and ${myarray[1]}
is the second line of the data.
What you are looking for is a two-dimensional array. See for instance this.
If you want an array with the content of the first line, you can do like this:
$ read -a arr < demo.txt
$ echo ${arr[0]}
1
$ echo ${arr[1]}
2
$ echo ${arr[2]}
3
readarray rows < demo.txt
for row in "${rows[@]}";do
row_array=(${row})
first=${row_array[0]}
echo ${first}
done
Since 3 out of 5 answers ignore the OPs request to use readarray
I'm guessing no one will downvote me for adding another that also fails to use readarray
.
Paste the following code unaltered into an Ubuntu bash command line (not tried in any other environment)
# Create test array
echo -e "00 01 02 03 04
10 11 12 13 14
20 21 22 23 24
30 31 32 33 34" > original.txt;
# Reformat test array as a declared bash variable.
sed 's/^/"/g; s/$/"/g; 1s/^/declare my2d=(\n/; $s/$/\n);/' original.txt > original.sh;
# Source the bash variable.
source original.sh;
# Get a row.
declare row2=(${my2d[2]});
# Get a cell.
declare cell3=${row2[3]};
echo -e "Cell [2, 3] holds [${cell3}]";
Cell [2, 3] holds [23]
The four sed
groups do the following:
s/^/"/g;
- prepend double quotes to each lines/$/"/g;
- append double quotes to each line1s/^/declare my2d=(\n/;
- prepend declare my2d=(
to file$s/$/\n);
- append );
to fileThis gets too messy to be worth using if your array elements have whitespace in them