it-swarm.com.ru

Как использовать readarray в bash для чтения строк из файла в 2D массив

Допустим, у меня есть текстовый файл 'demo.txt', в котором есть таблица, подобная этой:

1 2 3    
4 5 6    
7 8 9    

Теперь я хочу прочитать каждую строку отдельно, используя команду readarray в bash, поэтому я пишу:

readarray myarray < demo.txt   

Проблема в том, что это не работает. Если я попытаюсь напечатать «myarray» с помощью:

echo $myarray

Я получил:

1 2 3

Также, если я напишу:

echo ${myarray[1]}

Я получил:

4 5 6

Вместо:

2

как я и предполагал. Это почему? Как можно получить доступ к каждой строке отдельно и в этой строке получить доступ к каждому участнику? 

12
user3206874

Это ожидаемое поведение. readarray создаст массив, где каждый элемент массива является строкой на входе. 

Если вы хотите увидеть весь массив, вам нужно использовать

echo "${myarray[@]}"

поскольку echo "$myarray будет выводить только myarray[0], а ${myarray[1]} - это вторая строка данных.

То, что вы ищете, это двумерный массив. Смотрите, например, это .

Если вам нужен массив с содержимым первой строки, вы можете сделать так:

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

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

Как можно получить доступ к каждой строке отдельно и в этой строке получить доступ к каждому участнику?

Согласно Справочное руководство Bash , Bash предоставляет одномерные индексированные и ассоциативные переменные массива. Таким образом, вы не можете ожидать matrix[1][2] или что-то подобное для работы. Однако вы можете эмулировать матричный доступ, используя ассоциативные массивы bash, где ключ обозначает множественное измерение.

Например, 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
2
bishop

Чтобы расширить ответ Дэмиена (и потому что я пока не могу отправлять комментарии ...), вы просто повторяете чтение. Я имею в виду что-то вроде следующего

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

Я надеюсь, что вы уже нашли решение (извините за удар ...). Я наткнулся на эту страницу, помогая учить друга, и подумал, что другие могут сделать то же самое.

2
Eric

Извините за удар, но я считаю, что есть простое и очень чистое решение для вашего запроса:

$ 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
Sebastien