web-dev-qa-db-fra.com

Supprime tous les fichiers d'un répertoire (ne touchez aucun dossier ni aucun de leurs dossiers)

Je voudrais savoir si rm peut supprimer tous les fichiers d'un répertoire (mais pas les sous-dossiers ni les fichiers des sous-dossiers)?

Je sais que certaines personnes utilisent:

rm -f /direcname/*.*

mais cela suppose que le nom du fichier a une extension que tous ne possèdent pas (je veux que tous les fichiers - avec ou sans extension soient supprimés).

17
toop

Bien que find vous permette de supprimer des fichiers en utilisant -exec rm {} \;, vous pouvez utiliser 

find /direcname -maxdepth 1 -type f -delete

et c'est plus rapide. L'utilisation de -delete implique l'option -depth, qui signifie que le contenu du répertoire de processus est précédé du répertoire.

34
troller
find /direcname -maxdepth 1 -type f -exec rm {} \;

Explication:

  • find recherche les fichiers et les répertoires dans /direcname
  • -maxdepth le limite à rechercher des fichiers et des répertoires qui sont des enfants directs de /direcname
  • -type f limite la recherche aux fichiers
  • -exec rm {} \; exécute la commande rm {} pour chaque fichier (après substitution du chemin du fichier à la place de {}).
7
huon

Je voudrais savoir si rm peut supprimer tous les fichiers d’un répertoire (mais pas les sous-dossiers ni les fichiers des sous-dossiers)?

C'est facile:

$ rm folder/*

Sans le -r, la commande rm ne touchera pas les sous-répertoires ni les fichiers qu'ils contiennent. Cela ne supprimera que les fichiers de la variable folder et non les sous-répertoires ou leurs fichiers.

Vous verrez errors vous dire que folder/foo est un répertoire qui ne peut pas être supprimé, mais cela ne vous pose pas de problème. Si vous voulez éliminer ces messages, redirigez simplement STDERR:

$ rm folder/* 2> /dev/null

Soit dit en passant, le statut de sortie de la commande rm peut ne pas être zéro, vous ne pouvez donc pas vérifier les erreurs rm. Si c'est important, vous devrez faire une boucle:

$ for file in *
> do
> [[ -f $file ]] && rm $file
> [[ $? -ne 0 ]] && echo "Error in removing file '$file'"
> done

Cela devrait fonctionner dans BASH même si les noms de fichiers contiennent des espaces.

3
David W.

Vous pouvez utiliser

find /direcname -maxdepth 1 -type f -exec rm -f {} \;
2
tonio

Une solution Shell (sans la méthode de recherche non standard -maxdepth) serait

for file in .* *; do
   test -f "$file" && rm "$file"
done
2
Jens

Unix n'est pas DOS. Il n'y a pas de champ "extension" spécial dans un nom de fichier. Tous les caractères après un point font simplement partie du nom et sont appelés suffixe. Il peut y avoir plus d'un suffixe, par exemple.tar.gz. Le caractère global Shell * correspond au caractère .; il est inconscient des suffixes. Donc, le *.* MS-DOS est juste * sous Unix.

Presque. * ne correspond pas aux fichiers qui commencent par .. Les objets nommés avec un point en tête sont, par convention, "cachés". Ils n'apparaissent pas non plus dans ls sauf si vous spécifiez -a.

(Cela signifie que les entrées de répertoire . et .. pour "self" et "parent" sont considérées comme masquées.)

Pour faire correspondre les entrées cachées également, utilisez .*

La commande rm ne supprime pas les répertoires (lorsqu'elle n'est pas utilisée de manière récursive avec -r) . Essayez rm <directory> et voyez. Même si le répertoire est vide, il refusera.

Ainsi, la façon dont vous supprimez tous les fichiers (non cachés), les pipes, les périphériques, les sockets et les liens symboliques d'un répertoire (tout en laissant les sous-répertoires seuls) est la suivante:

rm /path/to/directory/*

supprimer également ceux qui commencent par .:

rm /path/to/directory/{*,.*}

Cette syntaxe est l'expansion d'accolade. L'expansion des accolades n'est pas une correspondance de motif; c'est juste un raccourci pour générer plusieurs arguments, dans ce cas:

rm /path/to/directory/* /path/to/directory/.*

cette expansion a lieu d’abord en premier lieu, puis l’effacement est effectué pour générer les noms à supprimer.

Notez que différentes solutions publiées ici ont divers problèmes:

find /path/to/directory -type f -delete

# -delete is not Unix standard; GNU find extension
# without -maxdepth 1 this will recurse over all files
# -maxdepth is also a GNU extension
# -type f finds only files; so this neglects to delete symlinks, fifos, etc.

Les solutions de recherche GNU ont l’avantage de fonctionner même si le nombre d’entrées à supprimer dans le répertoire est énorme: trop important pour passer un seul appel à rm. Un autre avantage est que le -delete intégré ne présente pas de problème pour transmettre des noms de chemin amusants à une commande externe.

La solution de contournement portable pour le problème de trop d'entrées de répertoire consiste à répertorier les entrées avec ls et de diriger vers xargs:

( cd /path/to/directory ; ls -a | xargs rm -- )

Les parenthèses signifient "faire ces commandes dans un sous-processus"; De cette façon, l’effet de cd est oublié, ce qui est utile dans les scripts. ls -a inclut les fichiers cachés.

Nous incluons maintenant un -- après rm qui signifie "ceci est la dernière option; tout le reste est un argument sans option". Cela nous protège des entrées de répertoire dont les noms sont indissociables des options. Que se passe-t-il si un fichier s'appelle -rf et termine le premier argument? Ensuite, vous avez rm -rf ... qui supprimera les sous-répertoires.

1
Kaz

Certains shells, notamment zsh et peut-être bash version 4 (mais pas la version 3), ont une syntaxe pour le faire.

Avec zsh, vous pouvez simplement taper

rm /dir/path/*(.)

et si vous souhaitez supprimer tout fichier dont le nom commence par foo, de manière récursive dans les sous-répertoires, vous pouvez le faire

rm /dir/path/**/foo*(.)

la fonctionnalité double étoile est (avec un IMHO meilleur achèvement interactif) à mon avis suffisante pour passer à zsh pour les shells interactifs. YMMV

Le suffixe entre parenthèses indique que vous souhaitez que seuls les fichiers (et non les liens symboliques ou les répertoires) soient développés par le shell zsh.

Le moyen le plus simple de le faire est d'utiliser:

rm *

Pour supprimer des répertoires, vous devez spécifier l'option -r

rm -r

de sorte que vos répertoires et tout ce qu'ils contiennent ne seront pas supprimés à l'aide de

rm *

selon la page de manuel de rm, son but est de supprimer des fichiers, ce qui explique pourquoi

0
Musher

Simple Shell Globbing fera:

% tree
.
├── 1
├── 2
├── 3
├── 4
├── 5
└── bar
    ├── a
    ├── b
    ├── c
    ├── d
    └── e

1 directory, 10 files

% rm -f *
rm: cannot remove ‘./bar’: Is a directory

% tree .
.
└── bar
    ├── a
    ├── b
    ├── c
    ├── d
    └── e

1 directory, 5 files

comme dans la réponse de Jens, vous devrez peut-être ajouter un second rm -f .*, mais ce n'est que si vous attendez des fichiers cachés dans votre répertoire principal. Il n'est pas nécessaire de vérifier le type (test -f), car l'option rm -f ne supprimera pas les répertoires. Toutefois, cela supprimera également les fichiers "spéciaux" tels que les liens symboliques et les dispositifs de blocage.

0
sleblanc