คำตอบสั้น ๆ :
\ls -afq | wc -l
(ซึ่งรวมถึง.และ..เพื่อลบ 2)
เมื่อคุณแสดงรายการไฟล์ในไดเรกทอรีสามสิ่งทั่วไปอาจเกิดขึ้น:
- การระบุชื่อไฟล์ในไดเรกทอรี นี่เป็นสิ่งที่หลีกเลี่ยงไม่ได้: ไม่มีวิธีนับไฟล์ในไดเรกทอรีโดยไม่ต้องระบุ
- เรียงลำดับชื่อไฟล์ สัญลักษณ์ตัวแทนเชลล์และ
lsคำสั่งทำเช่นนั้น
- การเรียก
statเพื่อดึงข้อมูลเมตาเกี่ยวกับแต่ละรายการไดเรกทอรีเช่นไม่ว่าจะเป็นไดเรกทอรี
# 3 แพงที่สุดเนื่องจากต้องโหลด inode สำหรับแต่ละไฟล์ ในการเปรียบเทียบชื่อไฟล์ทั้งหมดที่จำเป็นสำหรับ # 1 จะถูกเก็บไว้ในบล็อกไม่กี่บล็อก # 2 ทำให้เสียเวลา CPU แต่มักจะไม่ใช่ตัวจัดการดีล
หากไม่มีการขึ้นบรรทัดใหม่ในชื่อไฟล์แบบง่ายls -A | wc -lจะบอกให้คุณทราบถึงจำนวนไฟล์ที่มีในไดเรกทอรี ระวังว่าถ้าคุณมีนามแฝงlsสิ่งนี้อาจทำให้เกิดการโทรไปที่stat(เช่นls --colorหรือls -Fจำเป็นต้องรู้ประเภทของไฟล์ที่ต้องมีการเรียกไปstat) ดังนั้นจากบรรทัดคำสั่งโทรcommand ls -A | wc -lหรือ\ls -A | wc -lเพื่อหลีกเลี่ยงนามแฝง
หากมีการขึ้นบรรทัดใหม่ในชื่อไฟล์การขึ้นบรรทัดใหม่จะแสดงรายการหรือไม่ขึ้นอยู่กับตัวแปร Unix coreutils ของ GNU และ BusyBox เริ่มต้นที่จะแสดงขึ้น?บรรทัดใหม่ดังนั้นมันจึงปลอดภัย
โทรls -fเพื่อแสดงรายการโดยไม่ต้องเรียงลำดับ (# 2) สิ่งนี้จะเปิดโดยอัตโนมัติ-a(อย่างน้อยในระบบที่ทันสมัย) -fตัวเลือกอยู่ใน POSIX แต่ด้วยสถานะตัวเลือก; การใช้งานส่วนใหญ่รองรับ แต่ไม่ใช่ BusyBox ตัวเลือก-qจะแทนที่อักขระที่ไม่สามารถพิมพ์ได้รวมถึงการขึ้นบรรทัดใหม่ด้วย?; มันเป็น POSIX แต่ไม่รองรับโดย BusyBox ดังนั้นให้ละเว้นหากคุณต้องการการสนับสนุน BusyBox โดยมีค่าใช้จ่ายในการโอเวอร์โหลดไฟล์ที่ชื่อมีอักขระขึ้นบรรทัดใหม่
หากไดเรกทอรีไม่มีไดเรกทอรีย่อยรุ่นส่วนใหญ่findจะไม่เรียกstatใช้รายการของตน (การเพิ่มประสิทธิภาพไดเรกทอรีใบไม้: ไดเรกทอรีที่มีจำนวนลิงค์ 2 ไม่สามารถมีไดเรกทอรีย่อยได้ดังนั้นfindไม่จำเป็นต้องค้นหาข้อมูลเมตาของรายการยกเว้น เงื่อนไขเช่น-typeต้องการ) ดังนั้นfind . | wc -lวิธีพกพาและรวดเร็วในการนับไฟล์ในไดเรกทอรีโดยที่ไดเรกทอรีนั้นไม่มีไดเรกทอรีย่อยและไม่มีชื่อไฟล์ใดมี newline
หากไดเรกทอรีไม่มีไดเรกทอรีย่อย แต่ชื่อไฟล์อาจมีการขึ้นบรรทัดใหม่ให้ลองหนึ่งในไดเรกทอรีเหล่านี้ (ไดเรกทอรีที่สองควรจะเร็วกว่าหากได้รับการสนับสนุน แต่อาจไม่เด่นชัด)
find -print0 | tr -dc \\0 | wc -c
find -printf a | wc -c
ในทางกลับกันอย่าใช้findถ้าไดเรกทอรีนั้นมีไดเรกทอรีย่อย: แม้แต่find . -maxdepth 1เรียกstatทุกรายการ (อย่างน้อยด้วย GNU find และ BusyBox find) คุณหลีกเลี่ยงการเรียงลำดับ (# 2) แต่คุณจ่ายราคาของการค้นหา inode (# 3) ที่ฆ่าประสิทธิภาพ
set -- *; echo $#ในเปลือกไม่มีเครื่องมือภายนอกคุณสามารถเรียกใช้นับไฟล์ในไดเรกทอรีปัจจุบันด้วย นี่เป็นจุดไฟล์ (ไฟล์ที่มีชื่อขึ้นต้นด้วย.) และรายงาน 1 แทนที่จะเป็น 0 ในไดเรกทอรีว่าง นี่เป็นวิธีที่เร็วที่สุดในการนับไฟล์ในไดเรกทอรีขนาดเล็กเพราะมันไม่จำเป็นต้องเริ่มโปรแกรมภายนอก แต่ (ยกเว้นใน zsh) เสียเวลาสำหรับไดเรกทอรีขนาดใหญ่เนื่องจากขั้นตอนการเรียงลำดับ (# 2)
ใน bash นี่เป็นวิธีที่เชื่อถือได้ในการนับไฟล์ในไดเรกทอรีปัจจุบัน:
shopt -s dotglob nullglob
a=(*)
echo ${#a[@]}
ใน ksh93 นี่เป็นวิธีที่เชื่อถือได้ในการนับไฟล์ในไดเรกทอรีปัจจุบัน:
FIGNORE='@(.|..)'
a=(~(N)*)
echo ${#a[@]}
ใน zsh นี่เป็นวิธีที่เชื่อถือได้ในการนับไฟล์ในไดเรกทอรีปัจจุบัน:
a=(*(DNoN))
echo $#a
หากคุณมีชุดตัวเลือกให้แน่ใจว่าจะปิด:mark_dirsa=(*(DNoN^M))
ใน POSIX เชลล์ใด ๆ นี่เป็นวิธีที่เชื่อถือได้ในการนับไฟล์ในไดเรกทอรีปัจจุบัน:
total=0
set -- *
if [ $# -ne 1 ] || [ -e "$1" ] || [ -L "$1" ]; then total=$((total+$#)); fi
set -- .[!.]*
if [ $# -ne 1 ] || [ -e "$1" ] || [ -L "$1" ]; then total=$((total+$#)); fi
set -- ..?*
if [ $# -ne 1 ] || [ -e "$1" ] || [ -L "$1" ]; then total=$((total+$#)); fi
echo "$total"
วิธีการทั้งหมดเหล่านี้เรียงลำดับชื่อไฟล์ยกเว้น zsh one
ls -l|wc -lจะถูกปิดโดยหนึ่งเนื่องจากบล็อกทั้งหมดในบรรทัดแรกของการls -lส่งออก