Comment supprimer récursivement des sous-répertoires et des fichiers, mais pas le premier répertoire parent?

13

Je peux utiliser ce qui suit pour supprimer le répertoire cible et récursivement tous ses sous-répertoires et contenus.

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

Cependant, je ne souhaite pas que le répertoire cible soit supprimé. Comment supprimer uniquement les fichiers de la cible, les sous-répertoires et leur contenu?

Michael Prescott
la source

Réponses:

11

La réponse précédente est presque correcte. Cependant, vous ne devez pas citer les caractères glob du shell si vous voulez qu'ils fonctionnent. Voici donc la commande que vous recherchez:

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

Notez que le * est en dehors des guillemets doubles. Ce formulaire fonctionnerait également:

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

Si vous avez les *guillemets comme indiqué ci-dessus, il ne tentera que de supprimer le fichier unique nommé littéralement *dans le répertoire cible.

pioto
la source
1
Cela ne fonctionne pas avec les fichiers et dossiers cachés. Je devais le refaire avec un
The Unfun Cat
8

Trois autres options.

  1. Utiliser findavec -mindepth 1et -delete:

    −mindepth levels
    N'appliquez aucun test ni aucune action à des niveaux inférieurs aux niveaux (un entier non négatif).
    −mindepth 1 signifie traiter tous les fichiers à l'exception des arguments de ligne de commande.

    -delete
    Supprimer les fichiers; true si la suppression a réussi. Si la suppression a échoué, un message d'erreur est émis. Si −delete échoue, l'état de sortie de find sera différent de zéro (quand il finira par se terminer). L'utilisation de −delete active automatiquement l'option −depth.
    Testez soigneusement avec l'option -depth avant d'utiliser cette option.

    # 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. Utilisez find, mais avec des fichiers, pas des répertoires. Cela évite d'avoir à 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. Allez-y et supprimez le répertoire parent, mais recréez-le. Vous pouvez créer une fonction bash pour ce faire avec une seule commande; voici un simple doublure:

    rm -rf '/target/dir with spaces' ; mkdir '/target/dir with spaces'
Quack Quichotte
la source
2

Que diriez-vous

rm -rf /target/directory\ path/*

S'il peut y avoir des fichiers commençant par. dans le répertoire cible.

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

Cette seconde correspondra à tout commençant par un., Sauf. et .. Il échouera sur des noms comme .a, mais ce n'est pas très courant. Il pourrait être modifié si nécessaire pour couvrir tous les cas.

KeithB
la source
J'ai essayé les deux et ils ne fonctionnent pas pour moi. Peut-être est-ce parce que mon chemin de répertoire cible contient des espaces? rm -rf '/ target / directory path / *' Il ne donne aucune erreur, mais les sous-répertoires restent.
Michael Prescott
Vous devez échapper aux espaces, soit avec une barre oblique inverse (\) avant l'espace, soit en mettant le nom du répertoire entier entre guillemets ("). J'ai édité les exemples pour le montrer.
KeithB
Merci, j'ai essayé cela comme indiqué dans mon commentaire précédent et toujours pas. (J'utilise OS X, est-ce important?)
Michael Prescott
OS X devrait fonctionner correctement, c'est ce que j'utilise. Assurez-vous de ne pas utiliser de barre oblique inverse ni de guillemets. Un ou l'autre.
KeithB
Oui, en utilisant simplement les guillemets. Si je supprime le * et que j'utilise uniquement rm -rf "/ target / directory path /" le répertoire "directory path" sera supprimé avec les sous-répertoires "directory path". Si j'utilise le rm -rf "/ target / directory path / *", rien ne se passe.
Michael Prescott
2
find /target/directory/ -xdev -depth -mindepth 1 -exec rm -Rf {} \;
Sergey
la source