Bash - 从文件填充二维数组
Bash - populate 2D array from file
我知道这可能很简单,但我真的很努力。
问题描述:
我有一个坐标格式为的文本文件:
1 2
3 7
...
其中第一列 == 'x' 和第二列 == 'y' 坐标。
现在我想使用文件中的坐标填充一个大小为 N x M 的二维数组,方法是为文件和“.”中指定的点打印 'X'。否则。
示例:数组[1][2] = 'X',数组[3][7] = 'X',数组[0][1] = '.'
到目前为止我已经尝试过:
分离 x,y 列并将它们存储在数组中,如下所示:
xcoords="xcoords.txt"
ycoords="ycoords.txt"
head $geneFile | grep " " | awk -F' ' '{print }' > $xcoords
head $geneFile | grep " " | awk -F' ' '{print }' > $ycoords
readarray -t xarr < $xcoords
readarray -t yarr < $ycoords
但不能真正从这里移动(最终无法正常工作的 3,4 嵌套 for 循环)。
或者只是将文件存储在二维数组中。但是由于 bash 不支持二维数组(我知道有一些方法可以模拟它但不知道在这种情况下如何使用它)
readarray -t array < $geneFile #
像这样的循环会很棒 - 当然我想要得到类似“${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
任何advice/example如何实现呢?提前致谢!
有一种简单的方法可以将大小为M
×N
的二维数组编码为大小为M*N
的一维数组,例如:
A[p,q] ↔ B[p+q*M]
对于我们的任务:我们将从一开始就修复M
和N
,将所有数组项设置为.
,然后读取文件将相应的字段设置为X
:
#!/bin/bash
M=10
N=10
[[ && -f && -r ]] || { printf >&2 'arg must be readable file.\n'; exit; }
geneFile=
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
根据您的数据,输出为:
..........
..........
.X........
..........
..........
..........
..........
...X......
..........
..........
在这种情况下,另一种可能性是使用字符串而不是数组(细节留给 reader 或其他回答者)。
注意:以静默方式读取文件的循环会丢弃格式错误的行。
我知道这可能很简单,但我真的很努力。
问题描述:
我有一个坐标格式为的文本文件:
1 2
3 7
...
其中第一列 == 'x' 和第二列 == 'y' 坐标。
现在我想使用文件中的坐标填充一个大小为 N x M 的二维数组,方法是为文件和“.”中指定的点打印 'X'。否则。
示例:数组[1][2] = 'X',数组[3][7] = 'X',数组[0][1] = '.'
到目前为止我已经尝试过:
分离 x,y 列并将它们存储在数组中,如下所示:
xcoords="xcoords.txt" ycoords="ycoords.txt" head $geneFile | grep " " | awk -F' ' '{print }' > $xcoords head $geneFile | grep " " | awk -F' ' '{print }' > $ycoords readarray -t xarr < $xcoords readarray -t yarr < $ycoords
但不能真正从这里移动(最终无法正常工作的 3,4 嵌套 for 循环)。
或者只是将文件存储在二维数组中。但是由于 bash 不支持二维数组(我知道有一些方法可以模拟它但不知道在这种情况下如何使用它)
readarray -t array < $geneFile #
像这样的循环会很棒 - 当然我想要得到类似“${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
任何advice/example如何实现呢?提前致谢!
有一种简单的方法可以将大小为M
×N
的二维数组编码为大小为M*N
的一维数组,例如:
A[p,q] ↔ B[p+q*M]
对于我们的任务:我们将从一开始就修复M
和N
,将所有数组项设置为.
,然后读取文件将相应的字段设置为X
:
#!/bin/bash
M=10
N=10
[[ && -f && -r ]] || { printf >&2 'arg must be readable file.\n'; exit; }
geneFile=
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
根据您的数据,输出为:
..........
..........
.X........
..........
..........
..........
..........
...X......
..........
..........
在这种情况下,另一种可能性是使用字符串而不是数组(细节留给 reader 或其他回答者)。
注意:以静默方式读取文件的循环会丢弃格式错误的行。