Saya memiliki variabel yang berisi string yang dibatasi ruang:
line="1 1.50 string"
Saya ingin membagi string itu dengan spasi sebagai pembatas dan menyimpan hasilnya dalam array, sehingga berikut ini:
echo ${arr[0]}
echo ${arr[1]}
echo ${arr[2]}
output
1
1.50
string
Di suatu tempat saya menemukan solusi yang tidak berhasil:
arr=$(echo ${line})
Jika saya menjalankan pernyataan gema di atas setelah ini, saya mendapatkan:
1 1.50 string
[empty line]
[empty line]
Saya juga mencoba
IFS=" "
arr=$(echo ${line})
dengan hasil yang sama. Bisakah seseorang membantu?
set -f; arr=($string); set +f
tampaknya lebih cepat daripadaread -r -a <<< $string
.Jawaban:
Untuk mengkonversi string menjadi array, silakan gunakan
atau
Sangat penting untuk tidak menggunakan tanda kutip karena ini berhasil.
sumber
for i in ${arr[@]}; do echo $i; done
echo ${arr[@]}
$line
memiliki karakter globbing di dalamnya.mkdir x && cd x && touch A B C && line="*" arr=($line); echo ${#arr[@]}
memberi 3declare -a "arr=($line)"
akan mengabaikanIFS
pembatas di dalam string yang dikutipline='*'
,read -a arr <<<$line
selalu bekerja, tetapi hanyaarr=($line)
gagal.Coba ini:
sumber
line='*'
Dalam:
arr=( $line )
. "Split" dikaitkan dengan "glob".Wildcard (
*
,?
dan[]
) akan diperluas ke nama file yang cocok.Solusi yang benar hanya sedikit lebih kompleks:
Tidak ada masalah menggumpal; karakter split diatur
$IFS
, variabel yang dikutip.sumber
arr=($line)
dalam jawaban yang diterima menderita masalah globbing. Sebagai contoh, cobalah:line="twinkling *"; arr=($line); declare -p arr
.<<<
tetapi mungkin ide yang baik untuk tetap menggunakan tanda kutip ganda untuk konsistensi dan keterbacaan.Jika Anda membutuhkan ekspansi parameter, cobalah:
Misalnya, ambil kode berikut.
Jika direktori saat ini berisi file
a.txt
,b.txt
danc.txt
, mengeksekusi kode akan menghasilkan output berikut.sumber
sumber
tr
berlebihan tetapi harus melewatinya"${arr[@]}"
, bukan$arr