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
ls
komut bunu yapar.
- Çağrı
stat
Bö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 -l
dizinde 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 --color
veya ls -F
bir çağrı gerektirir dosya türünü, bilmemiz gerekir stat
), bu yüzden komut satırından, çağrı command ls -A | wc -l
veya \ls -A | wc -l
bir 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 -f
Sıralamaları olmadan girişleri listelemek için arayın (# 2). Bu otomatik olarak açılır -a
(en azından modern sistemlerde). -f
Seçenek POSIX'deki ancak isteğe bağlı statüsü ile olduğu; çoğu uygulama bunu destekler, ancak BusyBox'ı değil. Seçenek, -q
yeni 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 find
sahip olamaz , bu nedenle girişlerin meta verilerini aramaya gerek yoktur. gibi koşulu -type
gerektirir). 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, find
dizinin alt dizinleri varsa kullanmayın : hatta her girişe find . -maxdepth 1
çağrı stat
yapar (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_dirs
seç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 -l
nedeniyle ilk satırında toplam bloklara kapalı birer olurduls -l
çıktı