Kısa cevap:
\ls -afq | wc -l
(Bu içerir .ve ..böylece 2'yi çıkartın.)
Dosyaları bir dizinde listelediğinizde, üç ortak şey olabilir:
- Dizindeki dosya adlarının numaralandırılması. Bu kaçınılmazdır: Bir dizindeki dosyaları numaralandırmadan saymanın bir yolu yoktur.
- Dosya adlarını sıralama. Shell joker karakterler ve
lskomut bunu yapar.
- Çağrı
statBöyle bir dizin olup olmadığını her dizin girişi, hakkında meta verileri almak için.
# 3 en pahalısıdır çünkü her dosya için bir inode yüklenmesini gerektirir. Buna karşılık # 1 için gerekli olan tüm dosya isimleri kompakt bir şekilde birkaç blokta saklanır. # 2 biraz CPU zamanını boşa harcar ancak bu genellikle bir anlaşma bozucu değildir.
Dosya adlarında yeni satır yoksa, basit bir ls -A | wc -ldizinde kaç tane dosya olduğunu söyler. Sizin için bir takma ad varsa dikkatli olun ls, bu bir çağrı tetikleyebilir stat(ör ls --colorveya ls -Fbir çağrı gerektirir dosya türünü, bilmemiz gerekir stat), bu yüzden komut satırından, çağrı command ls -A | wc -lveya \ls -A | wc -lbir takma ad önlemek için.
Dosya adında yeni satırlar varsa, satır satırlarının listelenip listelenmemesi Unix değişkenine bağlıdır. GNU coreutils ve BusyBox varsayılan olarak ?newline görüntülemekte , böylece güvenlidirler.
ls -fSıralamaları olmadan girişleri listelemek için arayın (# 2). Bu otomatik olarak açılır -a(en azından modern sistemlerde). -fSeçenek POSIX'deki ancak isteğe bağlı statüsü ile olduğu; çoğu uygulama bunu destekler, ancak BusyBox'ı değil. Seçenek, -qyeni satırlar da dahil olmak üzere yazdırılamayan karakterleri değiştirir ?; bu POSIX'tir ancak BusyBox tarafından desteklenmez, bu nedenle, adı yeni satır karakteri içeren fazla sayılan dosyalar pahasına BusyBox desteğine ihtiyacınız varsa, bunu atlayın.
Dizinin alt dizini yoksa, sürümlerinin çoğu girişlerini findçağırmaz stat(yaprak dizini optimizasyonu: bağlantı sayısı 2 olan bir dizin alt dizinlere findsahip olamaz , bu nedenle girişlerin meta verilerini aramaya gerek yoktur. gibi koşulu -typegerektirir). Bu nedenle find . | wc -l, dizinde alt dizinlerin olmaması ve dosya adının yeni bir satır içermemesi şartıyla, bir dizindeki dosyaları saymanın taşınabilir ve hızlı bir yoludur.
Dizinde alt dizin bulunmuyorsa, ancak dosya adları yeni satırlar içeriyorsa, bunlardan birini deneyin (ikincisi destekleniyorsa daha hızlı olmalı, ancak belirgin şekilde olmayabilir).
find -print0 | tr -dc \\0 | wc -c
find -printf a | wc -c
Öte yandan, finddizinin alt dizinleri varsa kullanmayın : hatta her girişe find . -maxdepth 1çağrı statyapar (en azından GNU bulma ve BusyBox bulma ile). Sıralamadan kaçınır (# 2), ancak performansı düşüren bir inode aramasının (# 3) ücretini ödersiniz.
Dış araçları olmayan kabukta, geçerli dizindeki dosyaları ile çalıştırabilirsiniz set -- *; echo $#. Bu, nokta dosyalarını (adı başlayan dosyalar) özlüyor .ve boş bir dizinde 0 yerine 1 bildiriyor. Bu, küçük dizinlerdeki dosyaları saymanın en hızlı yoludur, çünkü harici bir program başlatmayı gerektirmez, ancak (zsh hariç) sıralama adımından (# 2) dolayı daha büyük dizinler için zaman harcar.
Kısacası, geçerli dizindeki dosyaları saymanın güvenilir bir yoludur:
shopt -s dotglob nullglob
a=(*)
echo ${#a[@]}
Ksh93'te, geçerli dizindeki dosyaları saymanın güvenilir bir yoludur:
FIGNORE='@(.|..)'
a=(~(N)*)
echo ${#a[@]}
Zsh'de, geçerli dizindeki dosyaları saymanın güvenilir bir yoludur:
a=(*(DNoN))
echo $#a
Eğer varsa mark_dirsseçeneği ayarlanmış, bunu kapatmak için emin olun: a=(*(DNoN^M)).
Herhangi bir POSIX kabuğunda bu, geçerli dizindeki dosyaları saymanın güvenilir bir yoludur:
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"
Bu yöntemlerin tümü, zsh dışında dosya adlarını sıralar.
ls -l|wc -lnedeniyle ilk satırında toplam bloklara kapalı birer olurduls -lçıktı