bash dinamik (değişken) değişken adları


12

Dinamik olarak öğeleri bir dizi manipüle ve bazı aritmetik yordamı oluşturmak için dizeleri bir dizi oluşturmak istiyorum.

for name in FIRST SECOND THIRD FOURTH FIFTH; do
    $name = $(( $6 + 1 ))
    $name = "${$name}q;d"
    echo "${$name}"; printf "\n"
done

Arzu $6eşitliği için aşağıdaki sonuç olacaktır 0.

1q;d
2q;d
3q;d
4q;d
5q;d

Ama bu hatayı alıyorum

reel_first_part.sh: line 18: FIRST: command not found
reel_first_part.sh: line 19: ${$name}q;d: bad substitution
reel_first_part.sh: line 18: FIRST: command not found
reel_first_part.sh: line 19: ${$name}q;d: bad substitution
reel_first_part.sh: line 18: FIRST: command not found
reel_first_part.sh: line 19: ${$name}q;d: bad substitution

Sanırım bu basit bir şey. Eskiden böyle bir şey yaptığımda çalışırdı

FIRST=$(( $6 + 1 ))
FIRST="${FIRST}q;d"

1
Biraz daha iyi açıklayabilir misin? Ne yapmaya çalıştığını gerçekten anlama.
nöron

"$ Name = $ ((6 $ + 1))" ne yapmalı?
PSkocik

@PSkocik Yapmayı umuyordumFIRST=$(( $6 + 1 ))
giannis christofakis

Yanıtlar:


16

Her şeyden önce =değişken bildirgede bir boşluk olamaz bash.

İstediğinizi elde etmek için kullanabilirsiniz eval.

Örneğin, sizinki gibi bir örnek komut dosyası:

#!/bin/bash
i=0
for name in FIRST SECOND THIRD FOURTH FIFTH; do
    eval "$name"="'$(( $i + 1 ))q;d'"
    printf '%s\n' "${!name}"
    i=$(( $i + 1 ))
done

Baskılar:

1q;d
2q;d
3q;d
4q;d
5q;d

evalDikkatli kullanın , bazı insanlar geçerli bir nedenle kötülük diyorlar.

declare çok işe yarar:

#!/bin/bash
i=0
for name in FIRST SECOND THIRD FOURTH FIFTH; do
    declare "$name"="$(( $i + 1 ))q;d"
    printf '%s\n' "${!name}"
    i=$(( $i + 1 ))
done

ayrıca yazdırır:

1q;d
2q;d
3q;d
4q;d
5q;d

Nedir !ünlem işareti printf '%s\n' "${!name}"için?
giannis christofakis

1
Onun bashparametre genişletme denilen dolaylı genişleme .. bunu
oku

1
Bash'in declare/ eval: ' a daha hoş bir alternatifi vardır printf -v varname '%fmt' args. Bazı bash tamamlama dahili işlevleri bunu referans olarak arama için kullanır. (depolanacak değişkenin adını iletir).
Peter Cordes

Not: Kullanım declareyalnızca yerel kapsamdaki değişkeni evalayarlarken , yaklaşım küresel olarak ayarlar.
kullanıcı

12

Başka bir değişkende adı saklanırken bir bash değişkenine başvurmak istiyorsanız, bunu aşağıdaki gibi yapabilirsiniz:

$ var1=hello
$ var2=var1
$ echo ${!var2}
hello

Erişmek istediğiniz değişkenin adını bu durumda var2 olarak kaydedersiniz. Ardından , erişmek istediğiniz değişkenin adını tutan bir değişken ${!<varable name>}olduğu yere <variable name>erişebilirsiniz.


Taşınabilir bir yol var eval var=\$$holderama evaltehlikeli!
gavenkoa

1
index=0;                                                                                                                                                                                                           
for name in FIRST SECOND THIRD FOURTH FIFTH; do
    name=$(($index + 1))
    echo "${name}q;d"
    index=$((index+1))
done

Denediğin bu mu?


1

Kodunuzdan ve istediğiniz çıktıdan ne alırım (yanlışsam beni düzeltin):
"İLK" / "İKİNCİ" / ... değişken adlarının bir faydası yok, sadece bir indeksli bir döngüye ihtiyacınız var .. .

Bu işi yapacak:

for i in {1..5} ; do echo $i"q;d" ; done


Evet, haklısın, ancak bir değişken ile aritmetik bir işlev yapmak istiyorum.
giannis christofakis

Bu aritmetik işleve bir örnek verebilir misiniz? Bunun için değişken adına ("THIRD" gibi) veya sadece dizin değerine mi ihtiyacınız var?
csny

SUM=$(($6 + $i)); echo $SUM"q;d", Ne yaptığımı görüyorum.
giannis christofakis
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.