J'essaie de lire un fichier contenant des lignes dans un tableau de Bash.
J'ai essayé ce qui suit jusqu'à présent:
a=( $( cat /path/to/filename ) )
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
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
La commande readarray
(également orthographié mapfile
) a été introduite dans bash 4.0.
readarray a < /path/to/filename
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[@]}"
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[@]}
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
#!/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