Belirli sayıda dosya içeren dizinleri bulma


14

Bunu findkomutla yapabileceğimi umuyordum ama elimde istediğimi yapmak için hiçbir test göremiyorum. Çalışma dizininde belirttiğim sayıdan daha az, daha fazla veya tam olarak içeren herhangi bir dizin bulabilmek istiyorum.

find . -filecount +10 # any directory with more than 10 entries
find . -filecount 20 # any directory with exactly 20 entries

Ama ne yazık ki böyle bir seçenek yok.


"ls -al | wc -l | grep" gibi bir şey deneyin
Vanadis

Yanıtlar:


17

Alt dizin adlarını ve içerdikleri dosya / dizin sayısını almak için bunu deneyebilirsiniz:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \;

Tüm alt dizinler için aynısını yapmak istiyorsanız (özyinelemeli bulma) bunu kullanın:

find . -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \;

Tam olarak 10 dosyaya sahip dizinleri seçmek için:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \; | 
  awk '$NF==10'

10 veya daha fazla:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \; | 
 awk '$NF>=10'

10 veya daha az:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{} '; ls '{}' | wc -l" \; | 
 awk '$NF<=10'

Yalnızca dizin adını saklamak istiyorsanız (örneğin, @evilsoup'un önerdiği gibi akışaşağıdaki başka bir işleme bağlamak istiyorsanız) bunu kullanabilirsiniz:

find . -maxdepth 1 -type d -exec bash -c "echo -ne '{}\t'; ls '{}' | wc -l" \; | 
 awk -F"\t" '$NF<=10{print $1}'

1
Sorgulayıcı başka bir şey için çıkış boru istiyorsa, dosya sayısını (yani son boşluk sınırlandırılmış sütun) kesmek için awk komutunu dahil etmek yararlı olabilir düşünüyorum.
evilsoup

1
@evilsoup iyi fikir, bitti.
terdon

Dizin adlarındaki boşlukları ve özel karakterleri desteklemek için; tek ve çift tırnak kullanımını tersine çevirmeyi deneyin:find . -type d -exec bash -c 'echo -ne "{} "; ls "{}" | wc -l' \; | awk '$NF<=10'
Håvard Geithus

3

Tam olarak $NUM dosyalar içeren hemen alt dizinleri listelemek için .

find -maxdepth 2 -mindepth 2 -type f -printf '%h\0' | awk -v num="$NUM" 'BEGIN{RS="\0"} {array[$0]++} END{for (line in array) if (array[line]==num) printf "%s\n", line}'

İçeren acil alt dizinleri listelemek için büyük daha $NUMdosyaları.

find -maxdepth 2 -mindepth 2 -type f -printf '%h\0' | awk -v num="$NUM" 'BEGIN{RS="\0"} {array[$0]++} END{for (line in array) if (array[line]>num) printf "%s\n", line}'

İçeren acil alt dizinleri listelemek için az daha $NUMdosyaları.

find -maxdepth 2 -mindepth 2 -type f -printf '%h\0' | awk -v num="$NUM" 'BEGIN{RS="\0"} {array[$0]++} END{for (line in array) if (array[line]<num) printf "%s\n", line}'

Öğeler boş karakterle sonlandırılır \0, bu nedenle yeni satırlar veya diğer beyaz boşluk türlerini içeren dosya adları doğru şekilde yorumlanır. %hHer dosyanın yazdırır dirname. awkardından her diziyle kaç kez karşılaştığını saymak için bir dizi kullanır ve koşullar karşılandığında yazdırır.

Yukarıda belirtilen komutların hiçbirinin sıfır dosya içeren dizinleri göstermeyeceğini lütfen unutmayın. Ayrıca dosyasıyla ben normal dosyalar, kastediyorum dikkat değil vs. bağlantıları, dizinler, priz, bloklar, adlandırılmış borular.

Bunu olabildiğince basit yapmaya çalıştım. Özyinelemeli alt dizinleri veya içindeki dosyaları bulmak istiyorsanız, değiştirilmiş bir komut gerekir. Hepsini listelemek için çok fazla olasılık var.


2

Bunu dene:

[bul. | wc -l` -eq 10] && echo "Bulundu"

[bul. | wc -l` -gt 10] && echo "Bulundu"

[bul. | wc -l` -lt 10] && echo "Bulundu"

Bu örneklerde, CURRENT dizininin tam olarak 10, 10'dan fazla ve 10'dan az dosya / dizin içerip içermediğini kontrol edebilirsiniz. Eğer bir sürü dizini kontrol etmeniz gerekiyorsa, sadece loop'u kullanın.


Çözümünüz ayrıca geçerli dizini ( .) sayar, buna göre değiştirmek isteyebilirsiniz.
terdon

Bu cevabın itişini seviyorum (çünkü kabukta bir şeyler yapmak için bir oburum), ancak gereksiz bir çağrıyı önlemek için testin içinde wc -l < <(printf %s\\n ./*)veya printf %s\\n ./* | wc -liçinde kullanmak daha iyi olur find. Bu, @terdon'un .sonuca dahil olma problemini de önleyecektir . Ancak, aynı zamanda a ile başlayan dosyaları yoksayma sorunuyla da karşılaşır .; Ben shopt -s dotglob(globs bir ile başlayan dosyaları maç yapmak için ., ama değil .veya ..) ile bunu çözecekti .
evilsoup

@terdon Önemli değil. Bu nihai çözüm değil, sadece örnek, fikir. Son sürümde -1 veya 10 ila 11 arasında bir değer değiştirebilirsiniz.
Eylül

Biliyorum ve fikir iyi, bu yüzden öneri yaptım.
terdon

@ terdon. Teşekkür ederim. Aşağıdakiler gibi birçok farklı gereksinim olabilir: Yalnızca dosyaları sayın, dizinleri, bağlantıları veya sabit bağlantıları saymayın. Alt dizinlerdeki dosyaları sayın veya saymayın. Gizli dosyaları sayın (.bashrc gibi) ... ... ifadeniz veeeeery loooong olabilir. :)
Eylül
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.