Anda tidak benar-benar membutuhkan banyak kode:
IFS=$'\n' sorted=($(sort <<<"${array[*]}"))
unset IFS
Mendukung spasi dalam elemen (selama itu bukan baris baru), dan berfungsi di Bash 3.x.
misalnya:
$ array=("a c" b f "3 5")
$ IFS=$'\n' sorted=($(sort <<<"${array[*]}")); unset IFS
$ printf "[%s]\n" "${sorted[@]}"
[3 5]
[a c]
[b]
[f]
Catatan: @sorontar telah menunjukkan bahwa kehati-hatian diperlukan jika elemen berisi karakter pengganti seperti *atau ?:
Bagian diurutkan = ($ (...)) menggunakan operator "split and glob". Anda harus mematikan glob: set -fatau set -o noglobatau shopt -op noglobatau elemen dari array *akan diperluas ke daftar file.
Apa yang terjadi:
Hasilnya adalah enam hal puncak yang terjadi dalam urutan ini:
IFS=$'\n'
"${array[*]}"
<<<
sort
sorted=($(...))
unset IFS
Pertama, IFS=$'\n'
Ini adalah bagian penting dari operasi kami yang memengaruhi hasil 2 dan 5 dengan cara berikut:
Diberikan:
"${array[*]}" meluas ke setiap elemen yang dibatasi oleh karakter pertama IFS
sorted=() membuat elemen dengan memisahkan setiap karakter IFS
IFS=$'\n' mengatur segala sesuatunya sehingga elemen diperluas menggunakan baris baru sebagai pemisah, dan kemudian dibuat sedemikian rupa sehingga setiap baris menjadi elemen. (yaitu Memisahkan di baris baru.)
Membatasi dengan baris baru penting karena begitulah cara sortkerjanya (pengurutan per baris). Memisahkan hanya dengan baris baru tidak begitu penting, tetapi diperlukan untuk mempertahankan elemen yang berisi spasi atau tab.
Nilai defaultnya IFSadalah spasi , tab , diikuti oleh baris baru , dan tidak sesuai untuk operasi kita.
Selanjutnya, sort <<<"${array[*]}"bagian
<<<, disebut di sini string , mengambil perluasan dari "${array[*]}", seperti dijelaskan di atas, dan memasukkannya ke dalam input standar sort.
Dengan contoh kami, sortdiberi makan string berikut ini:
a c
b
f
3 5
Sejak sort diurutkan , menghasilkan:
3 5
a c
b
f
Selanjutnya, sorted=($(...))bagian
Bagian $(...), yang disebut substitusi perintah , menyebabkan kontennya ( sort <<<"${array[*]}) berjalan sebagai perintah normal, sementara mengambil keluaran standar yang dihasilkan sebagai literal yang berjalan di mana pun $(...).
Dalam contoh kami, ini menghasilkan sesuatu yang mirip dengan sekadar menulis:
sorted=(3 5
a c
b
f
)
sorted then becomes an array that's created by splitting this literal on every new line.
Finally, the unset IFS
This resets the value of IFS to the default value, and is just good practice.
It's to ensure we don't cause trouble with anything that relies on IFS later in our script. (Otherwise we'd need to remember that we've switched things around--something that might be impractical for complex scripts.)
IFS, it'll split your elements into little pieces if they have whitespaces in them. Try the e.g. withIFS=$'\n'omitted and see!