Définir des variables avec un nom de variable

11

Quel est le problème avec ce script? J'essaie de définir A1 = 1, B1 = 1, C1 = 1

LIST="A B C"
for x in $LIST
do
    "$x"1=1
done

et le résultat est:

./x.: line 7: A1=1: command not found
./x.: line 7: B1=1: command not found
./x.: line 7: C1=1: command not found
Ake Blomberg
la source
1
Je ne pense pas que vous puissiez créer des variables en bash comme ça. Voici à quoi servent les tableaux.
Jakuje
3
Utilisez eval "$x"1=1. Bien que, comme l'a noté Jakuje, les tableaux soient probablement mieux adaptés à ce cas.
Andrea Corbellini
@AndreaCorbellini Vous devriez écrire cela comme réponse.
Sparhawk

Réponses:

21

Une affectation de variable a la forme d'un nom de variable, suivi du signe égal, suivi de la valeur (facultative).

Ceci est une mission valide:

ABC=123

"$x"1=1n'est pas une affectation valide, car "$x"1n'est pas un nom de variable. Il peut être eval uated à un nom de variable, mais ce n'est pas. Le shell, en fait, pense que c'est une commande.

Une façon de faire ce que vous voulez réaliser est la suivante:

eval "$x"1=1

Une autre façon dans bash (mais pas dans d'autres shells) est:

declare "$x"1=1

Ou aussi (encore une fois bash uniquement):

let "$x"1=1

(Il n'y a pas beaucoup de différence dans votre cas.)

Mais, comme Jakuje l'a noté dans les commentaires , vous voudrez probablement aller avec des tableaux, si votre shell en a (ksh, bash ou zsh).


Pour être complet:

  • evalexécute des commandes arbitraires. Donc, si sur le côté droit du signe égal, vous avez une variable qui se développe en une commande, cette commande sera exécutée. Le code suivant:

    x=a
    y='$(echo hello)'
    eval "$x=$y"
    

    est équivalent à a=hello.

  • declareest un bash intégré pour assigner des variables et n'exécutera aucune commande. Le code suivant:

    x=a
    y='$(echo hello)'
    declare "$x=$y"
    

    est équivalent à a='$(echo hello)'.

  • letest similaire à declare, car il n'exécute pas de commandes. Mais contrairement à declare, letpeut être utilisé pour des opérations arithmétiques:

    let a="1 + 2"

    est équivalent à a=3.

Andrea Corbellini
la source
Même ABC = 123n'est pas valide. Parce que l'espace est ajouté avant et après le equal(=)signe.
Mahendran Sakkarai
3

La FAQ bash a une entrée sur l'indirection. Dans la plupart des cas d'utilisation, ce que vous devez réellement faire est d'utiliser un tableau associatif ou indexé. Vous pouvez aussi utiliser

func_call_by_reference() { # Bash 4.3
    typeset -n ref=$1   # nameref to the variable named by the caller
    ref=( "val1" "val2" ... )  # return an array by reference
}

Voir cette entrée FAQ pour plus d'options pour ce faire tout en évitant les evalcitations en désordre .

Peter Cordes
la source
0

Vous pouvez utiliser du code comme suit. Dans votre shell de code s'exécute "$x"1=1comme une commande car ce n'est pas une affectation de variable valide.

LIST="A B C"
for x in $LIST
do
    a=$(echo "$x"1)
    let $a=1
done
AVJ
la source
Quel shell utilisez-vous? En utilisant bosh bash 4.1.7 et 4.3.11, je reçois des erreurs command not found <varname>=1lorsque j'essaie de le faire (évidemment avec <varname> étant la valeur dans laquelle je suis stocké a)
Eric Renouf
comme expliqué par @Andrea Corbellini, nous devons utiliser let, declare ou eval pour attribuer une valeur ..
AVJ
1
vous n'avez pas besoin echoici! Justement a="$x"1. Il lets'agit également d' un contexte arithmétique, vous ne pouvez donc lui affecter que des numéros.
Peter Cordes
declare $a=foobartravaux.
Peter Cordes