web-dev-qa-db-fra.com

Lire des lignes d'un fichier dans un tableau de Bash

J'essaie de lire un fichier contenant des lignes dans un tableau de Bash.

J'ai essayé ce qui suit jusqu'à présent:

Tentative1

a=( $( cat /path/to/filename ) )

Tentative2

index=0
while read line ; do
    MYARRAY[$index]="$line"
    index=$(($index+1))
done < /path/to/filename

Les deux tentatives ne renvoient qu'un tableau à un élément contenant la première ligne du fichier. Qu'est-ce que je fais mal?

Je cours bash 4.1.5

173

Dernière révision basée sur les commentaires de commentaire de BinaryZebra et testé ici . L'ajout de command eval permet de conserver l'expression dans le présent environnement d'exécution, tandis que les expressions précédentes ne sont conservées que pendant la durée de l'évaluation.

Utilisez $ IFS sans espaces\tabs, seulement newlines/CR

$ IFS=$'\r\n' GLOBIGNORE='*' command eval  'XYZ=($(cat /etc/passwd))'
$ echo "${XYZ[5]}"
sync:x:5:0:sync:/sbin:/bin/sync

Notez également que vous pouvez définir le tableau correctement mais que vous ne le lisez pas correctement - veillez à utiliser les deux guillemets doubles "" et les accolades {} comme dans l'exemple ci-dessus.


Modifier:

Veuillez noter les nombreux avertissements concernant ma réponse dans les commentaires sur une éventuelle expansion globale, en particulier commentaires de gniourf-gniourf à propos de mes tentatives précédentes de contourner

Avec tous ces avertissements en tête, je laisse toujours cette réponse ici (oui, bash 4 est sorti depuis de nombreuses années, mais je me souviens que certains macs âgés de seulement 2/3 ans ont une version antérieure à 4 comme shell par défaut)

Autres notes:

Peut également suivre la suggestion de drizzt ci-dessous et remplacer un sous-shell fourchu + chat par

$(</etc/passwd)

L’autre option que j’utilise parfois est de définir IFS dans XIFS, puis de restaurer après. Voir aussi réponse de Sorpigal qui n'a pas besoin de s'embêter avec cela

115
nhed

La commande readarray (également orthographié mapfile) a été introduite dans bash 4.0.

readarray a < /path/to/filename
215
chepner

Le moyen le plus simple de lire chaque ligne d'un fichier dans un tableau bash est le suivant:

IFS=$'\n' read -d '' -r -a lines < /etc/passwd

Maintenant, indexez simplement dans le tableau lines pour récupérer chaque ligne, par ex.

printf "line 1: %s\n" "${lines[0]}"
printf "line 5: %s\n" "${lines[4]}"

# all lines
echo "${lines[@]}"
94
Sorpigal

Une autre façon si le fichier contient des chaînes sans espaces avec 1 chaîne par ligne:

fileItemString=$(cat  filename |tr "\n" " ")

fileItemArray=($fileItemString)

Vérifier:

Imprimer tout le tableau:

${fileItemArray[*]}

Length=${#fileItemArray[@]}
20
Karanjot

Votre première tentative était proche. Voici l'approche simpliste utilisant votre idée.

file="somefileondisk"
lines=`cat $file`
for line in $lines; do
        echo "$line"
done
12
Atttacat
#!/bin/bash
IFS=$'\n' read  -d'' -r -a inlines  < testinput
IFS=$'\n' read  -d'' -r -a  outlines < testoutput
counter=0
cat testinput | while read line; 
do
    echo "$((${inlines[$counter]}-${outlines[$counter]}))"
    counter=$(($counter+1))
done
# OR Do like this
counter=0
readarray a < testinput
readarray b < testoutput
cat testinput | while read myline; 
do
    echo value is: $((${a[$counter]}-${b[$counter]}))
    counter=$(($counter+1))
done
2
Gopesh Bharadwaj