Hapus pohon direktori kosong (menghapus direktori sebanyak mungkin tetapi tidak ada file)


12

Misalkan saya memiliki pohon dir seperti ini:

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

Saya mencari perintah sehingga ketika saya input:

$ [unknown command] ROOTDIR

Keseluruhan dir tree dapat dihapus jika tidak ada file tetapi hanya dir di dalam keseluruhan tree . Namun, katakan jika ada file bernama hello.pdf di bawah SUBDIR1:

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

Maka perintah hanya harus menghapus SUBDIR2 dan di bawah.


Jawaban:


11

Alexis dekat. Yang perlu Anda lakukan adalah ini:

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

Yang pertama akan menelusuri pohon direktori sampai menemukan direktori kosong pertama, lalu hapus. Dengan demikian membuat direktori induk kosong yang kemudian akan dihapus, dll. Ini akan menghasilkan efek yang diinginkan (saya melakukan ini mungkin 10 kali seminggu, jadi saya cukup yakin itu benar). :-)


Mengapa -depthopsi perlu? find . -type d -empty -exec rmdir "{}" \;juga harus bekerja .... kan?
Abhishek A

4
Pertimbangkan jika Anda memiliki pohon (direktori saja) foo/bar/baz. Kecuali Anda menggunakan -depth, itu akan mencoba untuk menghapus footerlebih dahulu, gagal, dan Anda akan berakhir dengan foo/barsetelah berjalan.
l0b0

1
Kemungkinan alternatifnya adalah menggunakan +alih-alih ;agar Anda menghapus direktori. Karena Anda melakukannya dengan mendalam-pertama-tama anak-anak masih akan dihapus sebelum orang tua (mungkin tergantung pada versi rmdir / bash Anda dan bergantung pada rmdir tidak menghapus direktori kosong). Ini bekerja untuk saya di pesta di cygwin:mkdir -p a/b/c/d ; find a -depth -type d -exec rmdir {} +
idbrii

3
Teman-teman, dapatkan jawaban yang lebih ringkas dari Go2null di bawah ini! Tidak dapat memahami mengapa SE memberikan prioritas pada jawaban yang diterima daripada jawaban dengan sebagian besar upvotes dalam menampilkan jawaban di bawah pertanyaan. OP menerima jawaban terbaik yang tersedia pada saat pemilihannya, tetapi kemudian jawaban yang jauh lebih baik dapat datang yang diupayakan oleh masyarakat, bukan? (Tentu saja, ini adalah sesuatu untuk meta ...)
jamadagni

ini tidak bekerja untuk saya. hanya menghapus daun terdalam (SUBDIR3 dalam kasus ini)
joey baruch

23
find ROOTDIR -type d -empty -delete

sama dengan

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

tetapi menggunakan aksi "-delete" bawaan.

Perhatikan bahwa "-hapus" menyiratkan "-depth".


Kudos untuk jawaban yang paling ringkas dengan menggunakan delete bawaan yang ditemukan! Saya menambahkan ini ke skrip utils lokal saya!
jamadagni

3

Saya akan mencoba ini:

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

1

Berikut adalah beberapa persyaratan sebelum kami dapat melakukannya dengan aman:

  1. hapus subdirektori pertama dan kemudian direktori tingkat atas, yaitu kita perlu mengurutkan daftar direktori atau menggunakan flag rmdir --parents
  2. mulai ROOTDIR selalu dengan / atau ./ untuk menghindari kejutan dengan file yang dimulai dengan -
  3. menggunakan daftar direktori yang diakhiri NUL untuk bekerja dengan nama direktori dengan spasi

Inilah cara saya melakukan itu di shell:

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

Jika Anda tidak keberatan dengan beberapa kesalahan yang berlebihan maka Anda bisa memaksa menghapus semua direktori dengan orang tua dan Anda tidak perlu melakukan penyortiran (Anda tidak dapat mengurutkan string yang diakhiri NUL yang menambahkan perlu tr)

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

Kudos untuk penjelasan rinci tentang jawaban Anda. Saya mungkin telah menggunakan pendekatan yang sama, sampai saya belajar tentang -empty -deleteopsi finddalam jawaban @ go2null.
Davor Cubranic

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

5
Ini tidak akan berfungsi jika salah satu nama direktori berisi karakter spasi atau globbing. Ini umumnya ide yang buruk untuk menggunakan substitusi perintah pada daftar nama file. Ini terutama ide yang buruk dengan findkarena findmemiliki cara untuk melakukan pengolahan bersih: find … -exec.
Gilles 'SO- stop being evil'

Terima kasih kepada Gilles untuk menunjukkan hal itu. @lanzz, biasanya memposting hanya perintah tanpa menjelaskan apa yang dilakukannya (dan dalam hal ini, jebakan) tidak cukup. Silakan tambahkan jawaban Anda.
n0pe

0

Saya akan melakukan ini:

find ROOTDIR -type d | xargs -0 -I {} rmdir {}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.