Halaman Bash man menjelaskan penggunaan ${!a}
untuk mengembalikan konten variabel yang namanya isi a
(tingkat tipuan).
Saya ingin tahu cara mengembalikan semua elemen dalam array menggunakan ini, yaitu,
a=(one two three)
echo ${a[*]}
kembali
one two three
Saya ingin untuk:
b=a
echo ${!b[*]}
untuk mengembalikan yang sama. Sayangnya, tidak, tetapi kembali 0
sebagai gantinya.
Memperbarui
Mengingat jawaban, saya sekarang menyadari bahwa contoh saya terlalu sederhana, karena tentu saja, seperti:
b=("${a[@]}")
Akan mencapai apa yang saya katakan saya butuhkan.
Jadi, inilah yang saya coba lakukan:
LIST_lys=(lys1 lys2)
LIST_diaspar=(diaspar1 diaspar2)
whichone=$1 # 'lys' or 'diaspar'
_LIST=LIST_$whichone
LIST=${!_LIST[*]}
Tentu saja, dengan hati-hati membaca halaman manual Bash menunjukkan bahwa ini tidak akan berfungsi seperti yang diharapkan karena baris terakhir hanya mengembalikan indeks "array" $_LIST
(bukan array sama sekali).
Dalam kasus apa pun, yang berikut harus melakukan pekerjaan (seperti yang ditunjukkan):
LIST=($(eval echo \${$_LIST[*]}))
atau ... (rute yang saya tempuh, pada akhirnya):
LIST_lys="lys1 lys2"
...
LIST=(${!_LIST})
Dengan asumsi, tentu saja, elemen tidak mengandung spasi.
[@]
ke pointer_LIST="LIST_${whichone}[@]"
dan kemudian, gunakanLIST=("${!_LIST}")
untuk menyalin array. Sebaiknya gunakan nama variabel dengan huruf kecil untuk menghindari konflik dengan variabel lingkungan (Semua huruf besar).Jawaban:
Saya pikir penggunaan referensi tidak langsung dari variabel bash harus diperlakukan secara harfiah.
Misalnya. Untuk contoh asli Anda:
Untuk skenario nyata terakhir, saya percaya kode di bawah ini akan berfungsi.
Lebih baik menggunakan notasi
"${var[@]}"
yang menghindari mengacaukan$IFS
ekspansi dan parameter. Ini kode terakhirnya.sumber
Anda perlu menyalin elemen secara eksplisit. Untuk array yang diindeks:
Untuk array asosiatif (perhatikan bahwa itu
a
adalah nama variabel array, bukan variabel yang nilainya adalah nama variabel array):Jika Anda memiliki nama variabel dalam array, Anda bisa menggunakan metode elemen-demi-elemen dengan langkah ekstra untuk mengambil kunci.
(Peringatan, kode dalam posting ini diketik langsung di browser dan tidak diuji.)
sumber
\${!$name[@]}
di baris pertama, sehingga ekspansi pertama hanya dari '$ name', dan${!a[@]}
disimpan untuk eval, dan hal yang sama dalam for loop, dengan\${$name}
. Dua backslash lainnya sebelum '$ k' juga tidak diperlukan di sana.${!b[*]}
memperluas ke indeks yang digunakan dalam arrayb
.Apa yang Anda ingin harus dilakukan dalam dua langkah, sehingga
eval
akan membantu:eval echo \${$b[*]}
. (Catat\
yang memastikan bahwa yang pertama$
akan melewati langkah pertama, ekspansi variabel, dan hanya akan diperluas di langkah kedua oleheval
.)Menurut Parameter Ekspansi
!
keduanya digunakan untuk ekspansi tidak langsung ({!a}
), Awalan pencocokan nama (${!a*}
) dan Daftar kunci array (${!a[*]}
). Karena Daftar kunci larik memiliki sintaksis yang sama dengan ekspansi elemen + array tidak langsung yang Anda inginkan, yang kemudian tidak didukung seperti apa adanya.sumber
${!a}
memperluas ke nilai variabel yang namanya$a
. Ini agak dijelaskan dalam manual, dalam paragraf yang dimulai dengan "Jika karakter pertama parameter adalah titik seru (!
), level indirection variabel diperkenalkan."${!
itu agak tidak sopan karena jika Anda menggunakan array, tingkah lakunya berbeda.Untuk mengakses array secara tidak langsung, cukup tambahkan
[@]
ke variabel tidak langsungb=a[@]
.Jika variabel ini disetel:
Kemudian, ini akan berhasil:
Atau sederhananya:
Array seperti itu dapat disalin sebagai berikut:
Dan kemudian dicetak dengan:
Dalam satu skrip:
Tentu saja, semua yang di atas akan menyalin array yang tidak jarang. Satu di mana semua indeks memiliki nilai.
array jarang
Array jarang adalah salah satu yang mungkin memiliki elemen yang tidak didefinisikan.
Misalnya
a[8]=1234
mendefinisikan satu elemen, dan, dalam bash, 0 hingga 7 tidak ada.Untuk menyalin array yang jarang, gunakan metode ini
Cetak array lama:
Ganti nama array dan tangkap string:
Eval string yang dibuat, array baru telah ditentukan:
sumber