I know it's probably something easy but i'm struggling really hard with this.
Problem description:
I have a text file with coordinates in format:
1 2
3 7
...
where first column == 'x' and second column == 'y' coordinate.
Now i want to populate a 2D array of size N x M using this coordinates from file by printing 'X' for points that are specified in file and '.' otherwise.
Example: array[1][2] = 'X', array[3][7] = 'X', array[0][1] = '.'
So far I have tried:
separating x,y columns and storing them in arrays like this:
xcoords="xcoords.txt" ycoords="ycoords.txt" head $geneFile | grep " " | awk -F' ' '{print $1}' > $xcoords head $geneFile | grep " " | awk -F' ' '{print $2}' > $ycoords readarray -t xarr < $xcoords readarray -t yarr < $ycoords
But can't really move from here (ended up with not-working 3,4 nested for loops).
Or just storing a file in a 2D array. But since bash does not support 2D arrays (I know there are some ways to simulate it but don't know how to use it in this case)
readarray -t array < $geneFile #
Loops like this would be great - of course instead of fixed values I'd like to get something like "${xarr[i]}".
for (( i = 0; i < nRows; i++ )); do
for (( j = 0; j < nColumns; j++ )); do
if [[ $i == 5 ]] && [[ $j == 5 ]]; then # of course instead of fixed value here I'd like to get coordinates values.
printf "O"
else
printf "."
fi
done
printf "\n"
done
Any advice/example how to achieve it? Thanks in advance!
There's an easy way to encode a 2-dimensional array of size M
×N
into a 1-dimensional array of size M*N
, for example:
A[p,q] ↔ B[p+q*M]
For our task: we'll fix M
and N
from the beginning, set all the array terms to .
and then read the file to set the corresponding fields to X
:
#!/bin/bash
M=10
N=10
[[ $1 && -f $1 && -r $1 ]] || { printf >&2 'arg must be readable file.\n'; exit; }
geneFile=$1
array=()
for ((i=0; i<M*N; ++i)); do
array+=( '.' )
done
while read -r x y; do
[[ $x && $y ]] || continue
[[ $x = +([[:digit:]]) && $y = +([[:digit:]]) ]] || continue
((x=10#$x,y=10#$y))
(( x<M && y<N )) || continue
array[x+y*M]=X
done < "$geneFile"
# print to stdout
for((i=0;i<N;++i)); do
printf '%s' "${array[@]:i*M:M}" $'\n'
done
With your data, output is:
..........
..........
.X........
..........
..........
..........
..........
...X......
..........
..........
In this case, another possibility is to use a string instead of an array (details left to the reader or to another answerer).
Note: the loop that reads the file silently discards malformed lines.
来源:https://stackoverflow.com/questions/28645953/bash-populate-2d-array-from-file