Definire le variabili con un nome variabile


11

Cosa c'è di sbagliato in questo script? Sto cercando di definire A1 = 1, B1 = 1, C1 = 1

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

e il risultato è:

./x.: line 7: A1=1: command not found
./x.: line 7: B1=1: command not found
./x.: line 7: C1=1: command not found

1
Non penso che tu possa creare variabili in bash in questo modo. Ecco a cosa servono gli array.
Jakuje,

3
Usa eval "$x"1=1. Sebbene, come notato Jakuje, le matrici sono probabilmente più adatte a questo caso.
Andrea Corbellini,

@AndreaCorbellini Dovresti scriverlo come risposta.
Sparhawk,

Risposte:


21

Un'assegnazione di variabile ha la forma di un nome di variabile, seguito dal segno di uguale, seguito dal valore (facoltativo).

Questo è un compito valido:

ABC=123

"$x"1=1non è un compito valido, perché "$x"1non è un nome variabile. Può essere eval uated ad un nome di variabile, ma non lo è. La shell, infatti, crede che sia un comando.

Un modo per fare ciò che vuoi ottenere è questo:

eval "$x"1=1

Un altro modo in bash (ma non in altre shell) è:

declare "$x"1=1

O anche (di nuovo solo bash):

let "$x"1=1

(Non c'è molta differenza nel tuo caso.)

Ma, come Jakuje ha notato nei commenti , probabilmente vorrai andare con gli array, se la tua shell li ha (ksh, bash o zsh).


Per completezza:

  • evalesegue comandi arbitrari. Quindi, se sul lato destro del segno di uguale hai una variabile che si espande in qualche comando, quel comando verrà eseguito. Il seguente codice:

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

    è equivalente a a=hello.

  • declareè un built-in bash per assegnare variabili e non eseguirà alcun comando. Il seguente codice:

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

    è equivalente a a='$(echo hello)'.

  • letè simile a declare, in quanto non esegue comandi. Ma al contrario declare, letpuò essere usato per operazioni aritmetiche:

    let a="1 + 2"

    è equivalente a a=3.


Anche ABC = 123non è valido. Perché lo spazio viene aggiunto prima e dopo il equal(=)segno.
Mahendran Sakkarai,

3

Le FAQ di bash hanno una voce su indiretta. Nella maggior parte dei casi d'uso, ciò che si dovrebbe effettivamente fare è utilizzare un array associativo o indicizzato. Puoi anche usare

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
}

Vedi la voce FAQ per ulteriori opzioni per farlo, evitando comunque evalcitazioni disordinate .


0

Puoi usare il codice come segue. Nella shell del codice viene eseguito "$x"1=1come comando perché non è un'assegnazione variabile valida.

LIST="A B C"
for x in $LIST
do
    a=$(echo "$x"1)
    let $a=1
done

Che shell stai usando? Usando bosh bash 4.1.7 e 4.3.11 ottengo errori command not found <varname>=1quando provo a farlo (ovviamente con <varname> come valore in cui ho archiviato a)
Eric Renouf,

come spiegato da @Andrea Corbellini, dobbiamo usare let, dichiarare o valutare per assegnare valore ..
AVJ

1
non ti serve echoqui! Basta a="$x"1. Inoltre letè un contesto aritmetico, quindi è possibile assegnare solo numeri con esso.
Peter Cordes,

declare $a=foobarlavori.
Peter Cordes,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.