คุณไม่ต้องการรหัสมากขนาดนั้นทั้งหมด:
IFS=$'\n' sorted=($(sort <<<"${array[*]}"))
unset IFS
รองรับช่องว่างในองค์ประกอบ (ตราบใดที่ยังไม่ได้ขึ้นบรรทัดใหม่) และทำงานใน Bash 3.x
เช่น:
$ array=("a c" b f "3 5")
$ IFS=$'\n' sorted=($(sort <<<"${array[*]}")); unset IFS
$ printf "[%s]\n" "${sorted[@]}"
[3 5]
[a c]
[b]
[f]
หมายเหตุ: @sorontar ได้ชี้ให้เห็นว่าจำเป็นต้องมีการดูแลหากองค์ประกอบมีอักขระตัวแทนเช่น*
หรือ?
:
ส่วน sort = ($ (... )) กำลังใช้ตัวดำเนินการ "split and glob" คุณควรปิด glob: set -f
หรือset -o noglob
หรือshopt -op noglob
องค์ประกอบของ array เหมือน*
จะถูกขยายไปยังรายการไฟล์
เกิดอะไรขึ้น:
ผลที่ได้คือสุดยอดหกสิ่งที่เกิดขึ้นในคำสั่งนี้:
IFS=$'\n'
"${array[*]}"
<<<
sort
sorted=($(...))
unset IFS
ก่อนอื่น IFS=$'\n'
นี่เป็นส่วนสำคัญของการดำเนินงานของเราที่มีผลต่อผลลัพธ์ของ 2 และ 5 ด้วยวิธีต่อไปนี้:
ได้รับ:
"${array[*]}"
ขยายไปทุกองค์ประกอบคั่นด้วยอักขระตัวแรกของ IFS
sorted=()
สร้างองค์ประกอบโดยแยกตัวละครทุกตัวของ IFS
IFS=$'\n'
ตั้งค่าสิ่งต่าง ๆเพื่อให้องค์ประกอบถูกขยายโดยใช้บรรทัดใหม่เป็นตัวคั่นจากนั้นสร้างขึ้นในภายหลังในลักษณะที่แต่ละบรรทัดกลายเป็นองค์ประกอบ (เช่นแยกในบรรทัดใหม่)
การเพิ่มบรรทัดใหม่นั้นมีความสำคัญเนื่องจากเป็นวิธีsort
การทำงาน (การเรียงลำดับต่อบรรทัด) การแยกโดยเฉพาะบรรทัดใหม่นั้นไม่สำคัญเท่าไร แต่จำเป็นต้องเก็บรักษาองค์ประกอบที่มีช่องว่างหรือแท็บ
ค่าเริ่มต้นของIFS
เป็นช่องว่าง , แท็บตามด้วยการขึ้นบรรทัดใหม่และจะไม่เหมาะสำหรับการดำเนินงานของเรา
ถัดไปsort <<<"${array[*]}"
ส่วนที่
<<<
เรียกว่าที่นี่สตริงจะใช้เวลาการขยายตัวของตามที่อธิบายไว้ข้างต้นและฟีดมันเข้าไปในเข้ามาตรฐานของ"${array[*]}"
sort
จากตัวอย่างของเราให้sort
ป้อนสตริงต่อไปนี้:
a c
b
f
3 5
ตั้งแต่sort
ประเภทจะผลิต:
3 5
a c
b
f
ถัดไปsorted=($(...))
ส่วนที่
$(...)
ส่วนหนึ่งที่เรียกว่าคำสั่งเปลี่ยนตัวทำให้เนื้อหา ( sort <<<"${array[*]}
) เพื่อเรียกใช้คำสั่งเป็นปกติในขณะที่การส่งผลให้ การส่งออกมาตรฐานเป็นตัวอักษรที่จะไปที่ที่เคย$(...)
เป็น
ในตัวอย่างของเราสิ่งนี้สร้างสิ่งที่คล้ายกับการเขียนเพียง:
sorted=(3 5
a c
b
f
)
sorted
จากนั้นกลายเป็นอาร์เรย์ที่สร้างขึ้นโดยแยกตัวอักษรนี้ในทุกบรรทัดใหม่
ในที่สุด, unset IFS
สิ่งนี้จะรีเซ็ตค่าเป็นค่าIFS
เริ่มต้นและเป็นเพียงแนวทางปฏิบัติที่ดี
เพื่อให้แน่ใจว่าเราจะไม่สร้างปัญหากับสิ่งใดที่ต้องอาศัยในIFS
ภายหลังในสคริปต์ของเรา (ไม่เช่นนั้นเราจำเป็นต้องจำไว้ว่าเราได้เปลี่ยนสิ่งต่าง ๆ - สิ่งที่อาจเป็นไปไม่ได้สำหรับสคริปต์ที่ซับซ้อน)
IFS
มันจะแยกองค์ประกอบของคุณออกเป็นชิ้นเล็กชิ้นน้อยถ้าพวกเขามีพื้นที่ว่างในพวกเขา ลองเช่นกับIFS=$'\n'
ละเว้นดู!