Boş dizin ağaçlarını kaldırın (olabildiğince çok dizini kaldırmak, ancak dosyaları kaldırmak)


13

Diyelim ki böyle bir dir ağacı var:

ROOTDIR
    └--SUBDIR1
        └----SUBDIR2
            └----SUBDIR3

Ben girdiğinde öyle bir komut arıyorum:

$ [unknown command] ROOTDIR

Dosya yoksa, yalnızca tüm ağacın içindeki dizinler varsa tüm dir ağacı silinebilir . Ancak SUBDIR1 altında hello.pdf adlı bir dosya varsa diyelim:

ROOTDIR
    └--SUBDIR1
        └--hello.pdf
        └----SUBDIR2
            └----SUBDIR3

Bu durumda komutun yalnızca SUBDIR2 ve aşağısını silmesi gerekir.


Yanıtlar:


11

Alexis yakın. Yapmanız gereken şudur:

find . -type d -depth -empty -exec rmdir "{}" \;

Bu, önce ilk boş dizini bulana kadar dizin ağacını inceleyecek, sonra silecektir. Böylece daha sonra silinecektir, vb üst dizini boş yapma Bu istenen etkisi üretecektir (Bunu muhtemelen haftada 10 kez yaparım, bu yüzden doğru olduğundan eminim). :-)


-depthSeçenek neden gereklidir? find . -type d -empty -exec rmdir "{}" \;ayrıca çalışması gerekir .... değil mi?
Abhishek A

4
Ağacınız olup olmadığını düşünün (yalnızca dizinler) foo/bar/baz. Kullanmazsanız -depth, fooönce silmeye çalışır , başarısız olur ve koştuktan foo/barsonra sona erer .
l0b0

1
Muhtemelen alternatif +yerine ;dizinleri toplu kaldırmak yerine kullanmaktır . Önce bunu yaptığınızdan, çocuklar yine de ebeveynlerden önce kaldırılacaktır (muhtemelen rmdir / bash sürümünüze bağlı ve rmdir'e bağımlı olmayan dizinleri silmeme bağımlıdır). mkdir -p a/b/c/d ; find a -depth -type d -exec rmdir {} +
Cygwin'de bash'de

4
İnsanlar, aşağıda go2null'un çok daha özlü cevabını tercih edin! SE'nin neden soruların altındaki cevapları görüntülerken çoğu yukarı oy içeren cevaplar yerine kabul edilen cevaplara öncelik verdiğini anlayamıyorum. OP, seçtiği sırada mevcut olan en iyi cevabı kabul eder, ancak daha sonra topluluğun hangi oyları üstlenebileceğini daha iyi cevaplar alabilir mi? (Tabii ki, bu meta için bir şey ...)
jamadagni

bu benim için çalışmıyor. sadece en derin yaprağı siler (bu durumda SUBDIR3)
Joey Baruch

24
find ROOTDIR -type d -empty -delete

ile aynı

find ROOTDIR -type d -depth -empty -exec rmdir "{}" \;

ancak yerleşik "-delete" işlemini kullanır.

"-Delete" ifadesinin "-depth" anlamına geldiğini unutmayın.


Find'ın kendi dahili silmesini kullanarak en özlü cevap için Kudos! Bunu yerel yardımcı programlarıma ekliyorum!
jamadagni

3

Bunu denemek istiyorum:

find ROOTDIR -type d -depth -exec rmdir {} \;

1

Güvenli bir şekilde yapmadan önce bazı gereksinimler şunlardır:

  1. önce alt dizinleri ve ardından üst düzey dizinleri kaldırın, yani dizin listesini sıralamamız veya rmdir --parents flag kullanmamız gerekir
  2. Şununla başlayan dosyalarla sürprizlerden kaçınmak için ROOTDIR'i her zaman / veya ./ ile başlatın -
  3. boşluklu dizin adları ile çalışmak için NUL sonlandırılmış dizin listesini kullanın

Kabukta şöyle yapardım:

find ./ROOTDIR -type d | sort -r | tr '\n' '\000' | xargs -0 rmdir --ignore-fail-on-non-empty

Gereksiz hataların bir sakıncası yoksa, ebeveynlerle birlikte tüm dizinleri kaldırmaya zorlayabilirsiniz ve herhangi bir sıralama yapmanız gerekmez (tr'ye ihtiyaç duyan NUL sonlandırılmış dizeleri sıralayamazsınız)

find ./ROOTDIR -type d -print0 | xargs -0 rmdir --ignore-fail-on-non-empty --parents

Cevabınızın ayrıntılı açıklaması için şeref. @ Go2null'un cevabındaki -empty -deleteseçenekleri öğrenene kadar muhtemelen aynı yaklaşımı findkullanırdım.
Davor Cubranic

0
rmdir $(find ROOTDIR -type d | sort -r)

5
Dizin adlarından herhangi birinde boşluk veya globbing karakterleri varsa bu çalışmaz. Dosya adları listesinde komut ikamesi kullanmak genellikle kötü bir fikirdir. Özellikle kötü bir fikir findçünkü findtemiz bir şekilde işlem yapmak için bir yol vardır: find … -exec.
Gilles 'SO- kötü kalmayı kes'

Gilles'e bunu işaret ettiği için teşekkürler. @lanzz, genellikle ne yaptığını (ve bu durumda tuzakları) açıklamadan sadece bir komut göndermek yeterli değildir. Lütfen cevabınıza ekleyin.
n0pe

0

Bunu yapardım:

find ROOTDIR -type d | xargs -0 -I {} rmdir {}
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.