Bash - populate 2D array from file

痞子三分冷 提交于 2019-12-02 12:59:44

问题


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:

  1. 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).

  1. 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!


回答1:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!