Bagaimana cara menghapus subdirektori dan file secara rekursif, tetapi bukan direktori induk pertama?

13

Saya dapat menggunakan yang berikut ini untuk menghapus direktori target dan secara rekursif semua subdirektori dan kontennya.

find '/target/directory/' -type d -name '*' -print0 | xargs -0 rm -rf

Namun, saya tidak ingin direktori target dihapus. Bagaimana saya bisa menghapus hanya file dalam target, subdirektori, dan isinya?

Michael Prescott
sumber

Jawaban:

11

Jawaban sebelumnya hampir benar. Namun, Anda tidak boleh mengutip karakter glob shell jika Anda ingin mereka bekerja. Jadi, ini adalah perintah yang Anda cari:

rm -rf "/target/directory with spaces/"*

Perhatikan bahwa * berada di luar tanda kutip ganda. Formulir ini juga berfungsi:

rm -rf /target/directory\ with\ spaces/*

Jika Anda memiliki *tanda kutip seperti yang ditunjukkan di atas, maka itu hanya akan mencoba untuk menghapus satu file yang secara harfiah bernama *di dalam direktori target.

pioto
sumber
1
Ini tidak berfungsi dengan file dan folder tersembunyi. Saya harus melakukannya sekali lagi dengan
The Unfun Cat
8

Tiga opsi lagi.

  1. Gunakan finddengan -mindepth 1dan -delete:

    Levelstingkatan tingkat
    Jangan menerapkan tes atau tindakan apa pun pada level yang kurang dari level (bilangan bulat non-negatif).
    Indtahu ke 1 berarti memproses semua file kecuali argumen baris perintah.

    -hapus
    Hapus file; benar jika penghapusan berhasil. Jika penghapusan gagal, pesan kesalahan dikeluarkan. Jika failsdelete gagal, status keluar find akan menjadi nol (ketika akhirnya keluar). Penggunaan −delete secara otomatis mengaktifkan opsi −depth.
    Tes dengan hati-hati dengan opsi -depth sebelum menggunakan opsi ini.

    # optimal?
    # -xdev      don't follow links to other filesystems
    find '/target/dir with spaces/' -xdev -mindepth 1 -delete
    
    # Sergey's version
    # -xdev      don't follow links to other filesystems
    # -depth    process depth-first not breadth-first
    find '/target/dir with spaces/' -xdev -depth -mindepth1 -exec rm -rf {} \;
    



2. Gunakan find, tetapi dengan file, bukan direktori. Ini menghindari kebutuhan untuk rm -rf:

    # delete all the files;
    find '/target/dir with spaces/' -type f -exec rm {} \;

    # then get all the dirs but parent
    find '/target/dir with spaces/' -mindepth 1 -depth -type d -exec rmdir {} \;

    # near-equivalent, slightly easier for new users to remember
    find '/target/dir with spaces/' -type f -print0 | xargs -0 rm
    find '/target/dir with spaces/' -mindepth 1 -depth -type d -print0 | xargs -0 rmdir



3. Silakan dan hapus direktori induk, tetapi buat ulang. Anda bisa membuat fungsi bash untuk melakukan ini dengan satu perintah; inilah satu kalimat sederhana:

    rm -rf '/target/dir with spaces' ; mkdir '/target/dir with spaces'
quack quixote
sumber
2

Bagaimana tentang

rm -rf /target/directory\ path/*

Jika mungkin ada file yang dimulai dengan. di direktori target.

rm -rf "/target/directory path/*" "/target/directory path/.??*"

Detik ini akan cocok dengan semua yang dimulai dengan a., Kecuali. dan .. Itu akan gagal pada nama-nama seperti .a, tapi itu tidak terlalu umum. Itu bisa di-tweak jika perlu untuk menutupi semua case.

KeithB
sumber
Saya mencoba keduanya dan mereka tidak bekerja untuk saya. Mungkin karena jalur direktori target saya memiliki spasi di dalamnya? rm -rf '/ target / direktori path / *' Tidak memberikan kesalahan, tetapi subdirektori tetap ada.
Michael Prescott
Anda perlu melarikan diri dari spasi, baik dengan backslash (\) sebelum spasi, atau dengan melampirkan seluruh nama direktori dalam tanda kutip ("). Saya mengedit contoh untuk menunjukkan ini.
KeithB
Terima kasih, saya mencobanya seperti yang ditunjukkan pada komentar saya sebelumnya dan masih tidak jalan. (Saya menggunakan OS X, apakah itu penting?)
Michael Prescott
OS X seharusnya bekerja dengan baik, itulah yang saya gunakan. Pastikan Anda tidak menggunakan backslash dan quotes. Hanya satu atau yang lainnya.
KeithB
Ya, hanya menggunakan tanda kutip. Jika saya menghapus * dan jadi saya hanya menggunakan rm -rf "/ target / direktori path /" direktori "path direktori" akan dihapus bersama dengan subdirektori "path direktori". Jika saya menggunakan rm -rf "/ target / direktori path / *", tidak ada yang terjadi.
Michael Prescott
2
find /target/directory/ -xdev -depth -mindepth 1 -exec rm -Rf {} \;
Sergey
sumber