Boş alt klasörleri silin, üst klasörü saklayın


15

Kullandığımda

find /home/user/parentdir -type d -empty -delete

içindeki boş alt klasörleri yinelemeli olarak arar /home/user/parentdirve siler. Ancak /home/user/parentdirboşsa, parentdirklasörü de siler , bu benim için istenmeyen bir durumdur.

Bunu yedekleme veya bulut parentdiriçin rsyncbazı dosyalarda tutmak istiyorum . İşlemden sonra, boş klasörleri silmem gerekiyor, ancak parentdirher seferinde yeniden oluşturmak verimsiz görünüyor .

Saklanacak öneriniz var parentdirmı? .nocopyİçinde bir dosya oluşturmayı ve onu hariç tutmayı düşündüm rsync, ancak aşırıya kaçmış gibi görünüyor. Daha zarif bir yol var mı?


/ parentdir (/ / parentdir /) sonuna eğik çizgi eklerseniz bu bir fark yaratır mı?
Graham

6
-mindepth 1?
steeldriver

@Graham / parentdir / parentdir'i de siler, bu yüzden fark etmez.
TNT

ah, sonunda @Amourk'un cevabında bahsettiği * özledim.
Graham

Yanıtlar:


25

Sadece yap find /home/user/parentdir -mindepth 1 -type d -empty -delete.

Bak:

$ mkdir -p test1/test2
$ find test1 -type d
test1
test1/test2
$ find test1 -mindepth 1  -type d
test1/test2

find /home/user/parentdir/* AmourK yanıtında orada dosyaların bir yeri vardır ve overcomplicated zaman istenmeyen bir durumdur.


15

/*Sonuna ekleyerek parentdir, eylemi parentdirkendisi yerine parentdir öğesinin tüm alt dizinlerinde gerçekleştirirsiniz . Ve böylece aynı şekilde /home/user/eski komutta parentdirsilinmez, aşağıdaki komutta silinmez. *glob operatörü olarak adlandırılır ve herhangi bir karakter dizesiyle eşleşir.

find /home/user/parentdir/* -type d -empty -delete


7
Bu yaklaşımda dikkat edilmesi gereken bir şey, içinde çok sayıda dosya varsa /home/user/parentdir/, genişletilmiş glob aşılabilir ARG_MAXve bir argüman listesi çok uzun hataya neden olabilir. Glob'u */yalnızca dizinlerle eşleşecek şekilde değiştirerek bunun gerçekleşme olasılığını azaltabilirsiniz .
steeldriver

12
Ayrıca, bunun bir nokta ile başlayan hiçbir çocuk bulamayacağını unutmayın. Ve bir gün bunu fark edeceksiniz ve eğer ". *" İçin bir de bulursanız büyük bir incinme dünyasında olacaksınız (çünkü ". *" Eşleşir ".."). Bana nasıl bildiğimi sor.
Glenn Willen

1
@GlennWillen, bu hikayeyi anlatmanızı istemeden önce neden önümüzde içki içeren bir barda oturmalıyız?
Monty Harder

@MontyHarder Neyse ki olabileceği kadar kötü değildi. Lisemdeki bir Solaris makinesi olan ilk Unix sistemimdi. Tanrıya şükür 'rm' koşmuyordum, daha çok 'chown' yapıyordum. Ana dizindeki her şeyin sahipliğini düzeltmek için root kullanıyordum. Bunun yerine, kendime HER ana dizinin (ve tüm içeriklerinin) sahipliğini verdim ve hepsini geri koymak zorunda kaldım.
Glenn Willen

Yeni bir çalışanı bir yazılımın nasıl kurulacağı konusunda eğiten bir iş arkadaşım vardı. /tmpBir alt dizin oluşturmayı, orada bir sıkıştırılmış tarball'ı paketini açmayı, yükleyiciyi çalıştırmayı ve temizlemeyi içeriyordu . Yeni başlayanlar rm -rf /tmp/foo-installbunu yapmanın doğru yoluydu ve deneyimli el, en iyi III. / ve Enter tuşları birbirine bağlıydı. Yedekleme yazılımının geri yükleme diskinden önyükleme yapmak ve tüm sunucuyu teypten yeniden yüklemek zorunda kaldık.
Monty Harder

0

php-cli yüklüyse,

printf %s $(pwd) | php -r 'function f(string $dir){var_dump($dir);$dir.=DIRECTORY_SEPARATOR;foreach(glob("$dir*",GLOB_ONLYDIR) as $d){f($d);}global $original;if(substr($dir,0,-strlen(DIRECTORY_SEPARATOR))!==$original && empty(glob("$dir*"))){rmdir($dir);}}f(($original=stream_get_contents(STDIN)));'

istedin foreach (RecursiveIteratorIterator(RecursiveDirectoryIterator($dir)) as $p) if (empty($skipped)) $skipped = TRUE; elseif ($p->isDir()) @rmdir($p->getPathname());ya da buna yakın bir şey. $skippedilkini atlamaya özen gösterir, @rmdirbir dizini kaldırmaya çalışır ve boş değilse sessizce (@ @) başarısız olur.
chx

0

Yalnızca bir seviyeye ihtiyacınız olduğunda (bir üst klasörden ayrılır, ancak boş alt klasörleri siler), kullanımı kolay bir numaradır rmdir.

rmdir parent/*

Tüm boş alt klasörleri siler, ancak yalnızca dosyalar ve boş olmayan klasörler için bir hata yazdırır.

Bu özyinelemeli olarak çalışmaz, ancak klasör yapınızı biliyorsanız, böyle bir şey yapmanın en hızlı yolu olabilir

rmdir parent/*/*/* # deletes parent/a/b/c when empty
rmdir parent/*/* # deletes parent/a/b when it is now empty
rmdir parent/* # deletes parent/a when it is now empty

Avantajı: Hatırlaması kolay, yazması hızlı, yanlış parametre seçimi için çok az potansiyel.
Dezavantajı: Daha az esnek, muhtemelen terminalinizde çok fazla hata mesajı var.

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.