web-dev-qa-db-fra.com

Comment utiliser 'readarray' dans bash pour lire les lignes d'un fichier dans un tableau 2D

Disons que j'ai un fichier texte 'demo.txt' qui contient un tableau comme celui-ci:

1 2 3    
4 5 6    
7 8 9    

Maintenant, je veux lire chaque ligne séparément en utilisant la commande 'readarray' dans bash, alors j'écris:

readarray myarray < demo.txt   

Le problème est que cela ne fonctionne pas. Si j'essaie d'imprimer 'myarray' avec:

echo $myarray

Je reçois:

1 2 3

Aussi, si j'écris:

echo ${myarray[1]}

Je reçois:

4 5 6

Au lieu de:

2

comme je l'attendais. Pourquoi donc? Comment les accès individuels à chaque ligne peuvent-ils accéder à chaque membre? 

12
user3206874

C'est le comportement attendu. readarray créera un tableau où chaque élément du tableau est une ligne dans l'entrée. 

Si vous voulez voir tout le tableau que vous devez utiliser

echo "${myarray[@]}"

comme echo "$myarray ne produira que myarray[0], et ${myarray[1]} est la deuxième ligne des données.

Ce que vous recherchez est un tableau à deux dimensions. Voir par exemple this .

Si vous voulez un tableau avec le contenu de la première ligne, vous pouvez faire comme ceci:

$ 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

Comment les accès individuels à chaque ligne peuvent-ils accéder à chaque membre?

Selon le Manuel de référence Bash , Bash fournit des variables de tableau indexées et associatives unidimensionnelles. Donc, vous ne pouvez pas attendre matrix[1][2] ou similaire au travail. Cependant, vous pouvez émuler accès matriciel à l'aide de tableaux associatifs bash, où la clé indique une dimension multiple.

Par exemple, matrix[1,2] utilise la chaîne "1,2" en tant que clé de tableau associatif désignant la 1ère ligne, la 2ème colonne. En combinant ceci avec 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

Pour développer la réponse de Damien (et parce que je ne peux pas encore soumettre de commentaires ...), il vous suffit de lire la lecture. Ce que je veux dire est quelque chose comme ce qui suit

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

J'espère que vous avez déjà trouvé une solution (désolé de cogner ...). Je suis tombé sur cette page tout en aidant à enseigner à un ami et je me suis dit que d'autres pourraient en faire autant.

2
Eric

Désolé de vous heurter, mais je crois qu’il existe une solution simple et très propre à votre demande:

$ 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