如何在bash中使用'readarray'来读取文件中的行到2D数组中

时间:2014-10-29 15:53:46

标签: arrays bash

我们说我有一个文本文件' demo.txt'谁有这样的表:

1 2 3    
4 5 6    
7 8 9    

现在,我想使用' readarray'分别阅读每一行。命令在bash中,所以我写道:

readarray myarray < demo.txt   

问题在于它不起作用。如果我尝试打印'myarray&#39;用:

echo $myarray

我明白了:

1 2 3

另外,如果我写:

echo ${myarray[1]}

我明白了:

4 5 6

而不是:

2

正如我所料。这是为什么?如何分别访问每一行并在该行中访问每个成员?

6 个答案:

答案 0 :(得分:12)

这是预期的行为。 readarray将创建一个数组,其中数组的每个元素都是输入中的一行。

如果要查看整个阵列,则需要使用

echo "${myarray[@]}"

因为echo "$myarray只输出myarray[0],而${myarray[1]}是数据的第二行。

您正在寻找的是二维数组。例如,请参阅this

如果你想要一个包含第一行内容的数组,你可以这样做:

$ read -a arr < demo.txt 
$ echo ${arr[0]}
1
$ echo ${arr[1]}
2
$ echo ${arr[2]}
3

答案 1 :(得分:4)

readarray rows < demo.txt                                           

for row in "${rows[@]}";do                                                      
  row_array=(${row})                                                            
  first=${row_array[0]}                                                         
  echo ${first}                                                                 
done 

答案 2 :(得分:2)

要扩展Damien的答案(因为我还无法提交评论......),你只需要继续阅读。我的意思是类似下面的

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

我希望你已经找到了一个解决方案(抱歉...)。我偶然发现了这个页面,同时帮助教导了一个朋友,并认为其他人也可以这样做。

答案 3 :(得分:2)

  

如何分别访问每一行并在该行中访问每个成员?

根据Bash Reference Manual,Bash提供一维索引和关联数组变量。所以你不能期望matrix[1][2]或类似的工作。但是,您可以使用bash关联数组emulate进行矩阵访问,其中键表示多维。

例如,matrix[1,2]使用字符串“1,2”作为表示第1行第2列的关联数组键。将其与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

答案 4 :(得分:1)

很抱歉碰撞但我相信有一个简单而且非常干净的解决方案可以满足您的要求:

$ 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")'
$

答案 5 :(得分:0)

由于5个答案中有3个忽略了OP使用readarray的请求,我猜没有人会因为添加另一个同样不使用readarray的OP而拒绝我的投票。

将以下代码原封不动地粘贴到Ubuntu bash命令行(在任何其他环境中均未尝试)

代码

# 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]

说明

四个sed组执行以下操作:

  1. s/^/"/g;-在每行前加双引号
  2. s/$/"/g;-在每行后加双引号
  3. 1s/^/declare my2d=(\n/;-在declare my2d=(之前提交
  4. $s/$/\n);-附加);到文件

注意

如果您的数组元素中包含空格,这太乱了,不值得使用