Comment puis-je supprimer récursivement tous les fichiers d'une extension spécifique dans le répertoire actuel?

531

Comment supprimer en toute sécurité tous les fichiers avec une extension spécifique (par exemple .bak) du répertoire actuel et tous les sous-dossiers en utilisant une ligne de commande? Simplement, j'ai peur d'utiliser rmdepuis que je l'ai mal utilisé une fois et maintenant j'ai besoin de conseils.

utilisateur216038
la source

Réponses:

840

Vous n'avez même pas besoin d'utiliser rmdans ce cas si vous avez peur. Utiliser find:

find . -name "*.bak" -type f -delete

Mais utilisez-le avec précaution. Exécuter en premier:

find . -name "*.bak" -type f

pour voir exactement quels fichiers vous allez supprimer.

De plus, assurez - vous que -deleteest le dernier argument dans votre commande. Si vous le mettez avant le -name *.bak argument, il supprimera tout .

Voir man findet man rmpour plus d'informations et voir aussi cette question connexe sur SE:

Radu Rădeanu
la source
Comment est-ce différent de rm *.bak?
Sayantankhan
10
@ Bolt64 Votre rm *.bakne fonctionnera pas pour les sous-répertoires.
Radu Rădeanu
Avec les paramètres par défaut, rm *.baktous les fichiers se terminant par .bak ne seront supprimés que dans le répertoire actuel. Pour faire également des choses dans les sous-répertoires dont vous avez besoin soit pour manipuler globs, utilisez l'option -r ou utilisez l'exemple find.
Hennes
9
@Hennes Soyez prudent avec rm -r *.bak! Il supprime également les répertoires se terminant .bakpar tout leur contenu.
Radu Rădeanu
37
Assurez-vous que -deletec'est le dernier argument de votre commande. Si vous le mettez avant l' -name *.bakargument, il supprimera tout.
Michael
40
find . -name "*.bak" -type f -print0 | xargs -0 /bin/rm -f
les lokers
la source
1
Bienvenue sur askubuntu! Bien que cette réponse soit parfaitement valable, je ne pense pas qu'il soit avantageux de l'utiliser au lieu du -deletedrapeau find. Vous trouverez plus d’informations dans l’ entrée des manuels GNU permettant de supprimer des fichiers avec find .
Glutanimate
2
vous avez probablement raison, c'est juste une solution alternative, peut-être plus crue;)
lokers
11
Ce n'est pas simplement une alternative mais un exemple de la manière dont d'autres commandes peuvent être combinées avec le tube '|'. +1
Boris Pavlović
13
Ces solutions alternatives fonctionnent sur d'autres environnements qui manquent -delete (comme cygwin)
ciriarte
2
Je pense que c'est la meilleure réponse ici.
Léo Léopold Hertz
33

Exécutez d'abord la commande shopt -s globstar. Vous pouvez l'exécuter sur la ligne de commande et cela n'aura d'effet que dans cette fenêtre shell. Vous pouvez le mettre dans votre .bashrc, et tous les nouveaux obus démarrés le ramasseront. Cette commande a pour effet de créer des **/fichiers de correspondance dans le répertoire en cours et ses sous-répertoires de manière récursive (par défaut, cela a **/la même signification que */: uniquement dans les sous-répertoires immédiats). Ensuite:

rm **/*.bak

(ou gvfs-trash **/*.bakou qu'avez-vous).

Gilles
la source
21

Supprimer des fichiers n'est pour moi pas quelque chose que vous devriez utiliser rm. Voici une alternative:

sudo apt-get install gvfs     # install a tool that allows you to put stuff in the trash
alias "trash"="gvfs-trash"    # you can also put this in .bash_aliases or simply use the command without alias
trash *.bak                   # trash the files (thus moving them to the trash bin)

Comme le dit Flimm dans les commentaires:

Le paquet trash-clifait la même chose que gvfs-trashsans la dépendance sur gvfs.

Alors:

sudo apt-get install trash-cli

Vous n'avez pas besoin de créer un alias pour cela, car le trash-clipaquet fournit une commande trashqui fait ce que nous voulons.

Comme Eliah Kagan le précise dans de nombreux commentaires, vous pouvez également utiliser cette méthode de manière récursive find. Dans ce cas, vous ne pouvez pas utiliser d'alias. Les commandes ci-dessous supposent que vous avez installé trash-cli. Je résume les commentaires d'Eliah:

Cette commande trouve et affiche tous les .bakfichiers et liens symboliques situés n'importe où dans le répertoire en cours ou dans ses sous-répertoires ou en dessous.

find . -name '*.bak' -xtype f

Pour les supprimer, ajoutez un -execavec la trashcommande:

find . -name '*.bak' -xtype f -exec trash {} +

-xtype fsélectionne les fichiers et les liens symboliques vers les fichiers, mais pas les dossiers. Pour supprimer également les dossiers .bak, supprimez cette partie et utilisez -execdir-la pour éviter les cannot trash non-existenterreurs de .bakfichiers dans les .bakrépertoires:

find . -name '*.bak' -execdir trash {} +
don.joey
la source
4
"Ne pas utiliser rmpour supprimer des choses" est une déclaration controversée, mais je dois admettre qu'il est souvent plus sage d'utiliser quelque chose qui vous permettra d'annuler des choses.
Oli
2
Le paquet trash-clifait la même chose que gvfs-trashsans la dépendance sur gvfs.
Flimm
Je l'ai édité dans la réponse, la prochaine fois, n'hésitez pas à faire l'édition vous-même.
don.joey
@ don.joey Cette réponse semble indiquer find . -name "*.bak" -type fce que trash *.baksupprime. Est-ce vraiment ce que vous voulez dire? Vous pouvez déplacer des répertoires dans la corbeille avec trashou gvfs-trash, mais trash *.bakne déplacerez que les fichiers et les répertoires dont le nom se termine .baket qui résident immédiatement dans le répertoire en cours. Le shell se développe *.bak, donc trash *.bakn'affectera pas les .bakfichiers des sous-répertoires non nommés .bak.
Eliah Kagan
1
@ don.joey Oui ls *.bak(ce que je pense que vous voulez dire) répertorie les trash *.bakdéchets. find . -name '*.bak' -xtype f -exec trash {} +supprime tous les .bakfichiers n'importe où .. Il ne peut pas utiliser un alias, aussi installez trash-cliou écrivez gvfs-trash. Voici un exemple. -xtype fsélectionne les fichiers et les liens symboliques vers les fichiers, mais pas les dossiers. Pour supprimer également des .bak dossiers , utilisez la find . -name '*.bak' -execdir trash {} +méthode qui évite les cannot trash non existenterreurs de .bakfichiers dans les .bakrépertoires. N'hésitez pas à utiliser tout cela dans votre réponse.
Eliah Kagan
5

Si vous souhaitez supprimer tous les fichiers d'un certain type, mais seulement 1 dossier "profond" du dossier actuel:

find . -maxdepth 2 -name "*.log" -type f -delete

-maxdepth 2 car le répertoire actuel " . " compte comme premier dossier.

Hypocrite
la source
1

Réponse rapide:

  • Supprimez tous les fichiers portant le nom considéré ou postfix de manière récursive:

    find . -name '*.pyc' -type f -delete

  • Supprimez tous les répertoires avec le nom considéré récursivement:

    find ~ -path '*/__pycache__/*' -delete‍‍‍
    find ~ -type d -name '__pycache__' -empty -delete‍‍‍
    

    Un peu moins étroitement contrôlé, mais sur une seule ligne:

    find ~ -path '*/__pycache__*' -delete
    

[ NOTE ]:

dest une option de répertoire et fest une option de fichier.

Benyamin Jafari
la source
0

Si vous êtes dans un dépôt Git, vous pouvez utiliser:

git clean -fdx

Cela supprime les fichiers non suivis et les fichiers dans .gitignore.

Vasantha Ganesh K
la source