Si je comprends bien, je pense que vous voulez essentiellement parcourir les listes de valeurs, puis read
une autre dans la boucle.
Voici quelques options, 1 et 2 sont probablement les plus saines.
1. Émuler des tableaux avec des chaînes
Avoir des tableaux 2D serait bien, mais pas vraiment possible dans Bash. Si vos valeurs n'ont pas d'espaces, une solution de contournement pour les rapprocher consiste à coller chaque ensemble de trois nombres dans une chaîne et à diviser les chaînes à l'intérieur de la boucle:
for x in "1 2 3" "4 5 6"; do
read a b c <<< "$x";
read -p "Enter a number: " d
echo "$a - $b - $c - $d ";
done
Bien sûr, vous pouvez également utiliser un autre séparateur, par exemple for x in 1:2:3 ...
et IFS=: read a b c <<< "$x"
.
2. Remplacez le tuyau par une autre redirection pour libérer stdin
Une autre possibilité est d'avoir la read a b c
lecture d'un autre fd et de diriger l'entrée vers celle-ci (cela devrait fonctionner dans un shell standard):
while read a b c <&3; do
printf "Enter a number: "
read d
echo "$a - $b - $c - $d ";
done 3<<EOF
1 2 3
4 5 6
EOF
Et ici, vous pouvez également utiliser une substitution de processus si vous souhaitez obtenir les données d'une commande: while read a b c <&3; ...done 3< <(echo $'1 2 3\n4 5 6')
(la substitution de processus est une fonctionnalité bash / ksh / zsh)
3. Prenez plutôt la contribution de l'utilisateur de stderr
Ou, à l'inverse, en utilisant un tuyau comme dans votre exemple, mais avec l'entrée utilisateur read
de stderr
(fd 2) au lieu de stdin
la provenance du tuyau:
echo $'1 2 3\n4 5 6' |
while read a b c; do
read -u 2 -p "Enter a number: " d
echo "$a - $b - $c - $d ";
done
La lecture stderr
est un peu étrange, mais fonctionne en fait souvent dans une session interactive. (Vous pouvez également ouvrir explicitement /dev/tty
, en supposant que vous voulez réellement contourner toutes les redirections, c'est ce que des choses comme less
utilise pour obtenir l'entrée de l'utilisateur même lorsque les données y sont acheminées.)
Bien que l'utilisation de ce stderr
type puisse ne pas fonctionner dans tous les cas, et si vous utilisez une commande externe à la place read
, vous auriez au moins besoin d'ajouter un tas de redirections à la commande.
Voir aussi Pourquoi ma variable est-elle locale dans une boucle "en lecture", mais pas dans une autre boucle apparemment similaire? pour certains problèmes concernant ... | while
.
4. Découpez des parties d'un tableau selon vos besoins
Je suppose que vous pouvez également approximer un tableau 2D-ish en copiant des tranches d'un tableau unidimensionnel normal:
data=(1 2 3
4 5 6)
n=3
for ((i=0; i < "${#data[@]}"; i += n)); do
a=( "${data[@]:i:n}" )
read -p "Enter a number: " d
echo "${a[0]} - ${a[1]} - ${a[2]} - $d "
done
Vous pouvez également affecter ${a[0]}
etc. à a
, b
etc si vous voulez des noms pour les variables, mais Zsh le ferait beaucoup plus bien .