คุณสามารถโทรหายูทิลิตี้ภายนอก (ดูคำตอบอื่น ๆ ) แต่มันจะทำให้สคริปต์ของคุณช้าลงและเป็นการยากที่จะทำให้การประปาถูกต้อง
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 -fA
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 -cwc -m
การนับไบต์หรืออักขระด้วยwcการขึ้นบรรทัดใหม่ต่อท้ายจากคำสั่ง หากคุณต้องการความยาวของเส้นทางแบบบัญญัติเป็นไบต์ก็เท่ากับ
$(($(readlink -f /etc/fstab | wc -c) - 1))
ในการรับเป็นตัวอักษรให้ลบ 2
readlink -f /etc/fstabคือ11ตัวอักษร อย่าลืมบรรทัดใหม่ มิฉะนั้นคุณจะเห็น/etc/fstabluser@cern:~$เมื่อคุณวิ่งจากเปลือก