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

时间:2022-12-04 01:06:02

Let's say I have a text file 'demo.txt' who has a table in it like this:

假设我有一个文本文件'demo.txt',其中有一个表格,如下所示:

1 2 3    
4 5 6    
7 8 9    

Now, I want to read each line separately using the 'readarray' command in bash, so I write:

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

readarray myarray < demo.txt   

The problem is that it doesn't work. If I try to print 'myarray' with:

问题是它不起作用。如果我尝试打印'myarray':

echo $myarray

I get:

我明白了:

1 2 3

Also, if I write:

另外,如果我写:

echo ${myarray[1]}

I get:

我明白了:

4 5 6

Instead of:

代替:

2

as I expected. Why is that? How can accesses each line separately and in that line get access to each member?

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

5 个解决方案

#1


9  

This is the expected behavior. readarray will create an array where each element of the array is a line in the input.

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

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.

作为echo“$ myarray将仅输出myarray [0],而$ {myarray [1]}是数据的第二行。

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

#2


3  

readarray rows < demo.txt                                           

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

#3


1  

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

为了扩展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

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.

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

#4


1  

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.

根据Bash参考手册,Bash提供了一维索引和关联数组变量。所以你不能指望矩阵[1] [2]或类似的工作。但是,您可以使用bash关联数组模拟矩阵访问,其中键表示多维。

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:

例如,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

#5


0  

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

#1


9  

This is the expected behavior. readarray will create an array where each element of the array is a line in the input.

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

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.

作为echo“$ myarray将仅输出myarray [0],而$ {myarray [1]}是数据的第二行。

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

#2


3  

readarray rows < demo.txt                                           

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

#3


1  

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

为了扩展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

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.

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

#4


1  

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.

根据Bash参考手册,Bash提供了一维索引和关联数组变量。所以你不能指望矩阵[1] [2]或类似的工作。但是,您可以使用bash关联数组模拟矩阵访问,其中键表示多维。

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:

例如,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

#5


0  

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