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).
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.
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 {}
).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.
Vous pouvez utiliser
find /direcname -maxdepth 1 -type f -exec rm -f {} \;
Une solution Shell (sans la méthode de recherche non standard -maxdepth) serait
for file in .* *; do
test -f "$file" && rm "$file"
done
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.
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
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.