changement IFS temporairement avant une boucle for [duplicate]
Je sais que le SHELL
permet l'attribution de variables à avoir lieu immédiatement avant une commande, de sorte que cela IFS=":" read a b c d <<< "$here_string"
fonctionne ...
Ce que je me demandais, c'est que de telles affectations ne fonctionnent pas lorsqu'elles sont faites avec des instructions composées telles que des boucles? J'ai essayé quelque chose comme IFS=":" for i in $PATH; do echo $i; done
mais cela entraîne une erreur de syntaxe. Je pourrais toujours faire quelque chose comme oldIFS="$IFS"; IFS=":"; for....; IFS="$oldIFS"
, mais je voulais savoir s'il y avait un moyen pour que de telles affectations en ligne fonctionnent pour des instructions composées comme des for
boucles?
Réponses
for
est un mot réservé et en tant que tel suit des règles spéciales :
Les mots suivants sont reconnus comme des mots réservés:
! {} case do done elif else esac fi for if in then jusqu'à while
Cette reconnaissance ne doit avoir lieu que lorsqu'aucun des caractères n'est cité et que le mot est utilisé comme:
Le premier mot d'une commande
Le premier mot suivant l'un des mots réservés autres que case , for ou in
Le troisième mot dans une commande de cas (seulement dans est valide dans ce cas)
Le troisième mot d'une commande for (seuls les in et do sont valides dans ce cas)
Si tu essayes
IFS=":" for i in $PATH; do echo $i; done
, selon les règles ci-dessus, ce n'est pas une for
boucle, car le mot-clé n'est pas le premier mot de la commande. Mais votre intention pourrait être atteinte avec
IFS=: printf '%s\n' $PATH
$PATH
subit le fractionnement de mot :
comme prévu et chaque mot résultant est imprimé par printf
, suivi d'une nouvelle ligne.
Vous connaissez peut-être cette approche valide:
while IFS= read -r line; do
while
est le premier mot de la commande, et l' IFS
affectation s'applique à read
, donc tout va bien.