bir ağaçtaki tüm alt alt dizinleri bul


11

aşağıdaki yapı göz önüne alındığında:

oz123@debian:~/ $ tree .
.
├── a
│   ├── a1
│   ├── a2
│   └── a3
├── a1
│   ├── a11
│   ├── a12
│   └── a31
├── b
│   └── b1
│       ├── b11
│       │   └── b21
│       │       └── b31
│       ├── b12
│       └── b3
└── c

16 directories, 0 files

Tüm uç düğümleri nasıl bulurum?

İyi görünen aşağıdaki çözümleri buldum , ancak başarısız olacak test vakası olmadığını kanıtlamak zorundayım.

-linksEyaletlerin yardım sayfası :

'-Linkler' ile belirli sayıda bağlantıya sahip dosyaları da arayabilirsiniz. Dizinler normal olarak en az iki sabit bağlantıya sahiptir; onların. giriş ikincisidir. Alt dizinleri varsa, bunların her birinin üst dizinine .. adlı sabit bir bağlantısı vardır. . ve .. dizin girişleri find komut satırında belirtilmedikçe normalde aranmaz.

olası çözüm:

oz123@debian:~/ $ find .  -type d  -links 2
./a/a2
./a/a3
./a/a1
./c
./a1/a31
./a1/a11
./a1/a12
./b/b1/b12
./b/b1/b3
./b/b1/b11/b21/b31
  • Herkes daha iyi bir çözüm sağlayabilir (boru ve sed kullanmadan, bu performans ...
  • Herhangi bir dosya sisteminde çalışır mı?

3
-links 2Hile daha fazla performans bulamazsınız . Bu işe yaramaz btrfs.
Stéphane Chazelas

Yanıtlar:


3

Kendi çözümünüze ek olarak, -linkssadece Unix dizin bağlantısı kuralına uymayan dosya sistemlerinde çalışmadığını eklemek istiyorum. Açık man findseçeneğinden -noleafbunlar en azından CD-ROM, MS-DOS dosya sistemleri ve AFS birim bağlama noktalarıdır.

Bir referans olarak, bu soru zaten gerçekten daha yavaş olan ve genellikle sed / awk ve benzeri borulara başvuran farklı çözümlerle tartışılmıştır.


3

Biraz daha belirgin bir seçenek var -empty:

find . -type d -empty

Post. Tamam, bu şekilde haklısın dirs dosyaları ile çalışmaz.

Yani burada sabit bir dosya sistemi dayanılmaz sürümü:

find dtest/ -type d -exec sh -c "if [ \$(find {} -maxdepth 1 -type d | wc -l) -eq 1 ]; then echo {} ; fi" \;

2
Soruyu anlarsam, son dizinler dosya içerebilir. Bu, "boş" olmayacakları için bu dizinleri yazdırmaz ...
Stefan

@rush, subdirs boş olabilir veya olmayabilir
Oz123

@ Oz123 lütfen güncellememi kontrol edin, yeterince hızlı olmalı, ancak yolunuza göre biraz daha yavaş olmalıdır.
acele

@ acele, teşekkürler, ama gerçekten borulardan kaçınmam gerekiyor, işleri daha yavaş hale getirebilirler.
Oz123

1

find . -type d -links 2çoğu dosya sisteminde çalışır, ancak hepsi değil. Hangi dosya sistemi türlerinin dizinlerin kendilerine bir bağlantı içeren özelliğe sahip olduğunu bilmek dışında bir yolu olduğunu sanmıyorum. GNU find bunu dinamik olarak algılar (“find'ın -noleaf seçeneğini otomatik olarak açma” hakkında bir şeyler yazdırırsa, dosya sisteminizde bu özellik olmadığını bilirsiniz). En yaygın dosya sistemi türleri uygundur, ancak FAT veya btrfs değildir.

Emin olmak istiyorsanız, her dizini test etmeniz gerekir. Bunu yapmanın bir yolu, findher bir alt dizin için tekrar çağırmaktır .

find . -type d ! -exec sh -c '
   find "$1/." ! -name . -type d -prune | grep -q "^"' sh {} \; -print

(GNU ile find, biraz daha verimli hale getirmek için -pruneile değiştirebilirsiniz -print -quit).

Başka bir yol, çıktısını sonradan işlemektir find. İle find -depth, bir yaprak dizini kendi alt dizinini takip etmeyen dizindir.

find . -depth -type d -print0 |
awk -v RS='\0' '
    substr(previous, 1, length($0) + 1) != $0 "/"
    { previous = $0 }
'

0

Aşağıdaki çözümü deneyin (Linux, Unix ve OS X uyumlu olmalıdır):

find . -type d -execdir sh -c 'test -z "$(find "{}" -mindepth 1 -type d)" && echo $PWD/{}' ';'

Acele çözüm için benzer bir yaklaşım , ancak herhangi bir boru olmadan.

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.