คุณสามารถโทรหายูทิลิตี้ภายนอก (ดูคำตอบอื่น ๆ ) แต่มันจะทำให้สคริปต์ของคุณช้าลงและเป็นการยากที่จะทำให้การประปาถูกต้อง
zsh
ใน zsh คุณสามารถเขียน${#$(readlink -f /etc/fstab)}
เพื่อรับความยาวของการทดแทนคำสั่ง โปรดทราบว่านี่ไม่ใช่ความยาวของเอาต์พุตคำสั่ง แต่เป็นความยาวของเอาต์พุตโดยไม่ขึ้นบรรทัดใหม่
หากคุณต้องการความยาวที่แน่นอนของเอาท์พุทเอาท์พุทอักขระที่ไม่ใช่บรรทัดใหม่พิเศษในตอนท้ายและลบออกหนึ่ง
$((${#$(readlink -f /etc/fstab; echo .)} - 1))
หากสิ่งที่คุณต้องการคือเพย์โหลดในเอาต์พุตของคำสั่งคุณต้องลบสองอันที่นี่เพราะเอาต์พุตของreadlink -f
คือพา ธ แบบบัญญัติและบวกบรรทัดใหม่
$((${#$(readlink -f /etc/fstab; echo .)} - 2))
สิ่งนี้แตกต่างจาก${#$(readlink -f /etc/fstab)}
ในกรณีที่หายาก แต่เป็นไปได้ซึ่งเส้นทางแบบบัญญัตินั้นสิ้นสุดในการขึ้นบรรทัดใหม่
สำหรับตัวอย่างที่เฉพาะเจาะจงนี้คุณไม่จำเป็นต้องเป็นสาธารณูปโภคภายนอกเลยเพราะ zsh มีในตัวสร้างที่เทียบเท่ากับการผ่านการปรับปรุงประวัติศาสตร์readlink -f
A
echo /etc/fstab(:A)
ในการรับความยาวให้ใช้ตัวแก้ไขประวัติในการขยายพารามิเตอร์:
${#${:-/etc/fstab}:A}
หากคุณมีชื่อไฟล์ในตัวแปรfilename
นั่นก็${#filename:A}
คือ
กระสุนสไตล์ Bourne / POSIX
ไม่มีเชลล์ Bourne / POSIX บริสุทธิ์ (Bourne, Ash, mksh, ksh93, bash, yash …) มีส่วนขยายที่คล้ายกันที่ฉันรู้ หากคุณต้องการใช้การทดแทนพารามิเตอร์กับเอาต์พุตของการทดแทนคำสั่งหรือเพื่อทดแทนพารามิเตอร์ซ้อนให้ใช้ขั้นตอนต่อเนื่อง
คุณสามารถประมวลผลข้อมูลลงในฟังก์ชันได้หากต้องการ
command_output_length_sans_trailing_newlines () {
set -- "$("$@")"
echo "${#1}"
}
หรือ
command_output_length () {
set -- "$("$@"; echo .)"
echo "$((${#1} - 1))"
}
แต่มักจะไม่มีประโยชน์ ยกเว้นกับ ksh93 ที่ทำให้เกิด fork fork พิเศษเพื่อให้สามารถใช้เอาต์พุตของฟังก์ชันดังนั้นจึงทำให้สคริปต์ของคุณช้าลงและไม่ค่อยมีประโยชน์ในการอ่าน
อีกครั้งผลลัพธ์ของreadlink -f
คือเส้นทางที่เป็นที่ยอมรับบวกกับขึ้นบรรทัดใหม่ ถ้าคุณต้องการความยาวของเส้นทางที่ยอมรับลบ 2 แทน 1 command_output_length
ใน การใช้command_output_length_sans_trailing_newlines
จะให้ผลลัพธ์ที่ถูกต้องเฉพาะเมื่อเส้นทางแบบบัญญัติไม่ได้ขึ้นบรรทัดใหม่
ไบต์เทียบกับอักขระ
${#…}
ควรจะเป็นความยาวเป็นตัวอักษรไม่ใช่ในไบต์ซึ่งสร้างความแตกต่างในสถานที่หลายไบต์ เวอร์ชั่นล่าสุดของ ksh93 ที่สมเหตุสมผล, bash และ zsh คำนวณความยาวเป็นอักขระตามค่าของLC_CTYPE
เวลาที่การ${#…}
สร้างถูกขยาย เชลล์ทั่วไปส่วนใหญ่อื่น ๆ ไม่สนับสนุนโลแคลหลายไบต์จริง ๆ : ในขณะที่ประ 0.5.7, mksh 46 และ posh 0.12.3 ${#…}
ส่งคืนความยาวเป็นไบต์ หากคุณต้องการความยาวเป็นอักขระในวิธีที่เชื่อถือได้ให้ใช้wc
ยูทิลิตี้:
$(readlink -f /etc/fstab | wc -m)
ตราบใดที่$LC_CTYPE
กำหนดโลแคลที่ถูกต้องคุณสามารถมั่นใจได้ว่าสิ่งนี้จะเกิดข้อผิดพลาด (บนแพลตฟอร์มแบบโบราณหรือแบบ จำกัด ที่ไม่รองรับโลแคลหลายไบต์) หรือคืนความยาวที่ถูกต้องเป็นตัวอักษร (สำหรับ Unicode“ ความยาวเป็นตัวอักษร” หมายถึงจำนวนจุดโค้ด - จำนวนร่ายมนตร์เป็นอีกเรื่องหนึ่งเนื่องจากมีความซับซ้อนเช่นการรวมอักขระเข้าด้วยกัน)
หากคุณต้องการความยาวเป็นไบต์ตั้งLC_CTYPE=C
ชั่วคราวหรือการใช้งานแทนwc -c
wc -m
การนับไบต์หรืออักขระด้วยwc
การขึ้นบรรทัดใหม่ต่อท้ายจากคำสั่ง หากคุณต้องการความยาวของเส้นทางแบบบัญญัติเป็นไบต์ก็เท่ากับ
$(($(readlink -f /etc/fstab | wc -c) - 1))
ในการรับเป็นตัวอักษรให้ลบ 2
readlink -f /etc/fstab
คือ11ตัวอักษร อย่าลืมบรรทัดใหม่ มิฉะนั้นคุณจะเห็น/etc/fstabluser@cern:~$
เมื่อคุณวิ่งจากเปลือก