Komut satırını kullanarak bir dizindeki dosya sayısını nasıl alabilirim?


Yanıtlar:


239

Geniş bir "dosya" tanımı kullanmak

ls | wc -l

(gizli dosyaları saymadığını ve dosya adlarının yeni satır karakterleri içermediğini varsaydığını unutmayın).

Gizli dosyaları dahil etmek ( .ve hariç ..) ve yeni satır karakterleriyle ilgili sorunları önlemek için, kurallı yol:

find . ! -name . -prune -print | grep -c /

Veya yinelemeli olarak:

find .//. ! -name . -print | grep -c //

23
wcbir "kelime sayımı" programıdır. -lAnahtar satırları saymak için neden olmaktadır. Bu durumda, çıktıdaki satırları sayıyor ls. Bu, her zaman, belirli bir dizin için bir dosya sayımı almamın öğretildiği yoldu.
Sandy,

20
Lütfen çıktı bir boru ise lsbunu not edin ls -1.
lesmana 16

6
Bu, bir dizinde her şeyi alamaz - nokta dosyalarınızı özlediniz ve birkaç satır daha eklediniz. Boş bir dizin hala 1 satır döndürür. Ve eğer ararsanız ls -la, dizinde üç satır alacaksınız. Ve girişlerini ls -lA | wc -latlamak istiyorsun . Ancak yine de birer birer kapalı olacaksınız. ...

1
Boş bir dizin benim için 0 döndürür
James Roth

2
Adında yeni satırlara sahip dosyaları çift saymayacak olan düzeltilmiş bir yaklaşım şöyle olacaktır: ls -q | wc -l- ancak gizli dosyaların bu yaklaşım tarafından sayılmayacağına ve dizinlerin sayılacağına dikkat edin.
Godlygeek

31

Dosyanın dar tanımı için:

 find . -maxdepth 1 -type f | wc -l

Ve tabii ki -maxdepth 1dosyaları yinelemeli olarak saymak için atlayabilir (veya istediğiniz maksimum arama derinliği için ayarlayabilirsiniz).
user7089

1
Adı yeni bir satır içeren bir dosyanız varsa, bu yaklaşım hatalı olarak iki kez sayılır.
godlygeek

7
find -maxdepth 1 -type f -printf "\n" | wc -l
Adında

+1 Gizli dosyalara izin ver ve dizinleri yok sayar
Michael Durrant

14
ls -1 | wc -l

...

$ ls --help | grep -- '  -1'
    -1                         list one file per line

...

$ wc --help | grep -- '  -l'
    -l, --lines            print the newline counts

Not: Not ls - <sayı - bir> | wc - <letter-l>


10
Çoğu sürümü lsyapmak -1çıkışı bir boruya olduğunda otomatik olarak.
Dennis Williamson,

3
@Dennis bu ilginç bir uygulamanın çıktısının bir boruya gittiğini söyleyebileceğini bilmiyordum.
xenoterracide

1
Daha açık olduğu için bu sürümü + yaptım. Olsa da, evet ls eğer borulu ise -1 kullanır (deneyin: ls | cat), -1 sözdizimini daha açık buluyorum.
gabe.

3
@ xenoterracide: Bash'de:[[ -p /dev/stdin ]] && echo "stdin is from a pipe"
Dennis Williamson,

2
Testlerimde, dosya adlarını sıralamaktan kaçınmak için -f seçeneği sunmak anlamlı derecede daha hızlıydı. Dosya isimleriniz yeni satırlar içeriyorsa, ne yazık ki hala yanlış cevaplar alıyorsunuz.
Samuel Edwin Ward

10

Muhtemelen ls/ wcçifti kullanan en eksiksiz cevap

ls -Aq | wc -l

nokta dosyaları saymak istiyorsanız ve

ls -q | wc -l

aksi takdirde.

  • -Anokta dosyaları saymak, ancak atlamak .ve ...
  • -qyapmak lsile grafik olmayan karakterler, özellikle satır karakteri, yerine ?her dosya için çıktı üretmesi 1 satır yapım

lsTerminalden bir satırlık çıktı almak için (yani içine boru olmadan wc), -1seçenek eklenmelidir.

( lscoreutils 8.23 ​​ile test edilmiş davranışı )


2
Dediğiniz gibi, -1gerekli değildir. Gelince "Bu makul konsol çıkışı ile Dosya adlarında yeni satır kolları" , bu nedeniyle olduğunu -q(eğer yerine kullanması gerektiğini anahtarı -bhangi taşınabilir çünkü) olmayan yazdırılabilir dosya adı karakterleri ve <sekmesi> karakterlerin her bir örneği yazılacak "Kuvvetler <question-mark> ('?') karakteri olarak, çıktı bir terminal cihazına yönelikse uygulamalar varsayılan olarak bu seçeneği sağlayabilir. " Yani ls -Aq | wc -ltüm dosyaları / ls -qp | grep -c /
dirleri

Giriş için teşekkürler. Değişti -biçin -q.
Frax,

7

Geçerli dizinin en az bir gizli olmayan dosya içerdiğini biliyorsanız:

set -- *; echo "$#"

Bu açıkça herhangi bir glob için genelleştirilebilir.

Bir komut dosyasında, bunun konumsal parametrelerin üzerine yazılmasının bazen talihsiz bir yan etkisi vardır. Bunu bir alt kabuk kullanarak veya şöyle bir fonksiyonla (Bourne / POSIX sürümü) çalıştırabilirsiniz:

count_words () {
  eval 'shift; '"$1"'=$#'
}
count_words number_of_files *
echo "There are $number_of_files non-dot files in the current directory"

Alternatif bir çözümdür $(ls -d -- * | wc -l). Glob ise *, komut kısaltılabilir $(ls | wc -l). Çıktısını ayrıştırmak lsbeni her zaman tedirgin ediyor, ancak burada dosya adlarınız yeni satırlar içermediği veya lskaçtığınız sürece çalışmalıdır . Ve $(ls -d -- * 2>/dev/null | wc -l)(oysa, yani, bu, bu durumda 0 döndürür incelikle olmayan bir eşleştirme için defalarca talebi işleme avantajı vardır set *topak boş olabilir, bu yöntem derinde test gerektirir).

Dosya adları yeni satır karakterleri içeriyorsa, bir alternatif kullanmaktır $(ls -d ./* | grep -c /).

Bir globun genişlemesini geçmeye dayanan bu çözümlerden herhangi biri , çok fazla eşleşen dosya varsa ls, argüman listesi çok uzun bir hata ile başarısız olabilir .


1
Gerçekten 13,923 konumsal parametre oluşturmak istiyor musunuz? Ve yerel değişkeninizi yapmalı localveya ortadan kaldırmalısınız: eval $1=$#veya sadece kullanmalı echo $#ve yapmalısınız number_of_files=$(count_words *).
Dennis Williamson,

1
@Dennis: Meselenin bir kısmı çatallaşmadan kaçınmaktı. Sanırım bu 21. yüzyıl endişesi değil. Tamam, artık POSIX dışı mermilerle ilgilenmediğimi itiraf ediyorum, bu yüzden geçici değişkeni önleyebilirdim.
Gilles,

Neden birini çıkarttın $#(düzenlemeden önce yapmadın )?
Dennis Williamson,

@Dennis: Çataldan hala kaçınıyorum (peki, router gibi yavaş CPU'lu makinelerde fark yaratıyor) ve değişken bir isim vererek $1. Yani saymak istediğim ilk parametre olmayan parametre sayısı. (Kullanamıyorum shiftçünkü değişken ismini etrafta tutmam gerekiyor.) (Umm, şimdi ilk satır hakkında soru
Gilles,

@Dennis: düşününce, shiftdoğru zaman yaparsam kullanabilirim .
Gilles,

7

du --inodesYararlı buldum , ancak hangi sürümünün dugerekli olduğundan emin değilim . findVe kullanarak alternatif yaklaşımlardan çok daha hızlı olmalıdır wc.

Ubuntu 17.10'da aşağıdakiler çalışır:

du --inodes      # all files and subdirectories
du --inodes -s   # summary
du --inodes -d 2 # depth 2 at most

| sort -nrAzalan inode sayısına göre azalan sıralamak için ile birleştirin .


5

Eğer -U ekliyorsak, ls / wc çiftini kullanırken çok daha hızlı olacaktır (sıralama yapmayın).

ls -AqU | wc -l

1
-UGNU’ya özgü olsa da.
Stéphane Chazelas

4

Tree komutunu yükledikten sonra, sadece şunu yazın:

tree

Siz de gizli dosyalar istiyorsanız:

tree -a

Debian / Mint / Ubuntu Linux kullanıyorsanız, tree komutunu yüklemek için aşağıdaki komutu yazın:

sudo apt-get install tree

-L seçeneği, dizin ağacının maksimum görüntüleme seviyesini belirlemek için kullanılır. Tree komutu, yalnızca dizin sayısını değil, dizin ağacını istediğiniz kadar göz önüne alarak dizin sayısını da sayar.


Ağaç yazdığımda, bulunduğum dizinin ekranına bir tür ağaç çıktısı alıyorum ancak dosya sayısının nerede gösterildiğini göremiyorum.
charlesdarwin

2
find -maxdepth 1 -type f -printf . | wc -c
  • -maxdepth 1özyinelemesiz yapacak, findvarsayılan olarak özyinelemeli
  • -type f sadece dosyaları içerecek
  • -printf .sevimli bir dokunuş. dosya adı yerine her dosya için bir nokta yazdırır ve şimdi bu herhangi bir dosya adını işleyebilir ve ayrıca verileri kaydeder; sadece noktaları saymalıyız :)
  • | wc -c karakterleri sayar

1

Borusuz, telsiz kopya yok, çatal yok, sadece düz bash bir astar

$ fcount() { local f i=0; for f in *; do let i++; done; echo $i; }; fcount

1
Dizinde dosya yoksa, 1 değerini verir. Dosyaları saymaz, dosyaları ve dizinleri sayar.
steve

1

İşte yayınlanan bir Gilles'un çizgileri boyunca başka bir teknik :

word_count () { local c=("$@"); echo "${#c[@]}"; }
file_count=$(word_count *)

13,923 öğeli bir dizi oluşturur (eğer kaç tane dosya varsa).


Bu cdizinin amacı ne ? word_count() { echo "$#"; }Yeterli olacaktır. @Gilles çözeltisinin amacı, komut ikamesini kullanmaktan kaçınmak için (ksh93 dışındaki kabuklarda bir çatal ve boruyu içeren) sayımı geri dönen bir değişkende saklamaktır.
Stéphane Chazelas

1
find . -type f -maxdepth 1 |  wc -l 

Bu sadece geçerli dizindeki dosyaları listeleyebilir.


find . -type fdosyaları geçerli dizinde ve ayrıca yinelenerek alt dizinlerde bulacaktır.
dhag

0

Bunu dene umarım bu cevap size yardımcı olur

echo $((`ls -l | wc -l` -1 ))


0

Daha önce verilen bazı cevapların iyileştirilmesi ancak bu sefer açıkça yapılması.

$ tree -L 1 | tail -n 1 | cut -d " " -f 3

tailVe gibi bazı sevilen komutların kullanıldığını fark etmeye değer cut. Ayrıca, ağacın varsayılan olarak kullanılamadığını unutmayın. Yukarıdaki komut, ilk önce 1. seviyedeki dizin hakkında bilgi alır, sonra tail -n 1hedefimizin bulunduğu son satırı cutalır ve üçüncü kelimeyi almak için sona erer .

Örneğin, şunu bulmak /:

/ $ tree -L 1
.
├── 1
├── bin -> usr/bin
├── boot
├── dev
├── etc
├── home
├── lib -> usr/lib
├── lib64 -> usr/lib64
├── lost+found
├── media
├── mnt
├── opt
├── proc
├── root
├── run
├── sbin -> usr/sbin
├── srv
├── sys
├── tmp
├── usr
└── var

20 directories, 1 file
/ $ tree -L 1 | tail -n 1
20 directories, 1 file
/ $ tree -L 1 | tail -n 1 | cut -d " " -f 3
1

Öyleyse, dizin sayısını sormaya ne dersiniz?



Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.