Hapus subfolder kosong, simpan folder induk

15

Saat saya gunakan

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

itu terlihat secara rekursif untuk subfolder kosong di dalam /home/user/parentdirdan menghapusnya. Tetapi jika /home/user/parentdirjuga kosong, itu menghapus parentdirfolder juga, yang tidak diinginkan untuk saya.

Saya ingin menyimpan ini parentdiruntuk rsyncbeberapa file ke cadangan atau cloud. Setelah diproses, saya perlu menghapus folder kosong, tetapi tampaknya tidak produktif untuk membuat ulang parentdirsetiap waktu.

Ada saran untuk disimpan parentdir? Saya berpikir tentang membuat .nocopyfile di dalamnya dan mengecualikannya rsync, tetapi terlihat seperti berlebihan. Apakah ada cara yang lebih elegan?

TNT
sumber
jika Anda menambahkan garis miring / ke akhir / parentdir (ie / parentdir /) apakah itu membuat perbedaan?
Graham
6
-mindepth 1?
steeldriver
@Graham / parentdir / menghapus parentdir juga, jadi tidak ada bedanya.
TNT
ah, saya tahu saya melewatkan * di bagian akhir yang @Amourk sebutkan dalam jawabannya.
Graham

Jawaban:

25

Lakukan saja find /home/user/parentdir -mindepth 1 -type d -empty -delete.

Lihat:

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

Jawaban find /home/user/parentdir/* AmourK tidak diinginkan ketika ada banyak file dan terlalu rumit.

chx
sumber
15

Dengan menambahkan /*pada akhir parentdir, Anda melakukan tindakan pada semua subdirektori parentdir daripada pada parentdirdirinya sendiri. Dan dengan cara yang sama /home/user/tidak dihapus dalam perintah lama, parentdirtidak akan dihapus dalam perintah di bawah ini. *disebut operator glob dan cocok dengan serangkaian karakter apa pun.

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

AmourK
sumber
7
Satu hal yang perlu diperhatikan dengan pendekatan ini adalah jika ada banyak file di dalamnya /home/user/parentdir/, glob yang diperluas dapat melebihi ARG_MAX, yang mengakibatkan daftar argumen kesalahan yang terlalu panjang . Anda dapat mengurangi kemungkinan itu terjadi dengan mengubah */bola sehingga hanya cocok dengan direktori.
steeldriver
12
Berhati-hatilah karena ini tidak akan menemukan anak-anak yang memulai dengan titik. Dan suatu hari Anda akan menyadari ini, dan jika Anda juga menemukan ". *" Anda akan berada di dunia yang sangat terluka (karena ". *" Cocok ".."). Tanya saya bagaimana saya tahu.
Glenn Willen
1
@GlennWillen mengapa saya pikir kita harus duduk di bar dengan minuman di depan kita sebelum saya meminta Anda untuk menceritakan kisah ini?
Monty Harder
@MontyHarder Untungnya itu tidak seburuk yang seharusnya. Itu pada sistem Unix pertama saya, yang merupakan mesin Solaris yang dimiliki oleh sekolah menengah saya. Syukurlah aku tidak menjalankan 'rm', tetapi 'chown'. Saya menggunakan root untuk mencoba memperbaiki kepemilikan semua pada direktori home saya. Alih-alih, saya memberi diri saya kepemilikan SETIAP direktori home (dan semua isinya) dan kemudian harus mengembalikan semuanya.
Glenn Willen
Saya memiliki seorang rekan kerja yang melatih karyawan baru tentang cara memasang perangkat lunak. Itu melibatkan pergi ke /tmp, membuat subdirektori, membongkar tarball gzip di sana, menjalankan installer, dan membersihkan. Pemikiran pemula rm -rf /tmp/foo-installadalah cara yang tepat untuk melakukan itu, dan ketika tangan yang berpengalaman mengatakan "Noooooo" dalam kesan terbaiknya Darth-Vader-pada-akhir-Episode-III, newb menemukan cara yang sulit seberapa dekat / dan Masukkan kunci satu sama lain. Kami harus mem-boot dari disk pemulihan perangkat lunak cadangan dan memuat ulang seluruh server dari tape.
Monty Harder
0

jika Anda menginstal php-cli,

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)));'
hanshenrik
sumber
Anda ingin foreach (RecursiveIteratorIterator(RecursiveDirectoryIterator($dir)) as $p) if (empty($skipped)) $skipped = TRUE; elseif ($p->isDir()) @rmdir($p->getPathname());atau sesuatu yang dekat dengan itu. $skippedmengurus melewatkan yang pertama, @rmdirupaya untuk menghapus dir dan diam-diam (itulah @) gagal jika tidak kosong.
chx
0

Ketika Anda hanya membutuhkan satu level (meninggalkan folder induk, tetapi menghapus folder anak yang kosong), trik yang mudah adalah dengan menggunakannya rmdir.

rmdir parent/*

Menghapus semua subfolder kosong, tetapi hanya mencetak kesalahan untuk file dan folder tidak kosong.

Ini tidak bekerja secara rekursif, tetapi ketika mengetahui struktur folder Anda, ini mungkin cara tercepat untuk melakukan sesuatu

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

Keuntungan: Mudah diingat, cepat mengetik, sedikit potensi untuk memilih parameter yang salah.
Kerugian: Kurang fleksibel, mungkin banyak pesan kesalahan di terminal Anda.

allo
sumber