Supprimer tous les fichiers, sauf 1 000, dans un répertoire

13

Je laisse un script de génération de données s'exécuter trop longtemps maintenant avoir plus de 200 000 fichiers dont j'ai besoin à environ 1000. À partir de la ligne de commande Linux, existe-t-il un moyen facile de supprimer tous sauf 1000 de ces fichiers, où les fichiers qui seraient conservés n'aurait aucune dépendance sur le nom de fichier ou tout autre attribut?

Malcolm Regan
la source
Le processus qui a créé les fichiers avait-il une caractéristique qui reliait chaque fichier au précédent? Dans l'affirmative, il serait important de sélectionner au hasard pour obtenir un échantillon représentatif. Si le processus a généré des fichiers aléatoires par nature, vous pouvez tout supprimer après le premier 1000.
fixer1234

Réponses:

15

Supprimer tous les fichiers, sauf 1 000, dans un répertoire

Code:

find /path/to/dir -type f -print0 | sort -zR | tail -zn +1001 | xargs -0 rm

Explication:

  1. Liste tous les fichiers /path/to/diravec find;
    • print0: utiliser \0( caractère nul ) comme délimiteur de ligne; donc les chemins de fichiers contenant des espaces / sauts de ligne ne cassent pas le script
  2. Mélangez la liste des fichiers avec sort;
    • -z: utiliser \0(caractère nul) comme délimiteur, au lieu de \n(une nouvelle ligne)
    • -R: ordre aléatoire
  3. Supprimez les 1000 premières lignes de la liste aléatoire avec tail;
    • -z: traite la liste comme délimitée par zéro (comme avec sort)
    • -n +1001: afficher les lignes à partir de 1001 (c.-à-d. omettre les 1000 premières lignes)
  4. xargs -0 rm - supprimer les fichiers restants;
    • -0: délimité par zéro, encore une fois

Pourquoi c'est mieux que la solution de Quichotic *:

  1. Fonctionne avec les noms de fichiers contenant des espaces / sauts de ligne.
  2. N'essaye pas de créer des répertoires (qui peuvent déjà exister, btw.)
  3. Ne déplace aucun fichier, ne touche même pas aux 1000 "fichiers chanceux" en plus de les répertorier find.
  4. Évite de manquer un fichier au cas où la sortie de findne se termine pas par \n(nouvelle ligne) pour une raison quelconque.

* - crédit à quixotic pour | sort -R | head -1000, m'a donné un point de départ.

rld.
la source
En cours d'exécution sur CentOS 6, j'obtenais des erreurs concernant des opérandes invalides. Heureusement, je ne suis pas concerné par les espaces dans les chemins de fichiers, donc la suppression de ces opérandes a fonctionné pour moifind . -type f | sort -R | tail -n +1001 | xargs rm
brad
@brad Pourriez-vous fournir les messages d'erreur et votre version de find? Je vais essayer d'améliorer ma réponse, j'ai juste besoin de quelques commentaires pour travailler avec.
rld.
3
tail: invalid option -- 'z'la version de la queue que j'ai est 8.4
brad
J'ajouterais --no-run-if-empty à xargs pour éviter les erreurs s'il n'y a pas de fichier (après l'avoir exécuté deux fois par exemple)
fraff
1

Utilisez un répertoire temporaire, puis findtous vos fichiers, randomisez la liste avec sortet déplacez les 1000 premiers de la liste dans le répertoire temporaire. Supprimez le reste, puis replacez les fichiers dans le répertoire temporaire.

$ mkdir ../tmp-dir
$ find . -type f | sort -R | head -1000 | xargs -I "I" mv I ../tmp-dir/
$ rm ./*
$ mv ../tmp-dir/* .

Si se xargsplaint de la longueur de la ligne, utilisez un plus petit nombre avec headet répétez la commande au besoin (c. -à- changement -1000à -500et exécuter deux fois, ou le changement -200et l' exécuter 5 fois.)

Il échouera également à gérer les noms de fichiers qui incluent des espaces; comme le montre la réponse de @ rld , vous pouvez utiliser findl' -print0argument de, les -zarguments vers sortet head, et -0avec xargspour garantir une gestion correcte du nom de fichier.

Enfin, si le tmp-direxiste déjà, vous devez remplacer un nom de répertoire qui n'existe pas.

chimérique
la source
Cela échouera si l'un des noms de fichiers répertoriés par findinclut un espace.
rld.
0

Pour les utilisateurs de mac, le script suivant devrait faire l'affaire.

find . -type f -print0 | tr '\0' '\n' | sort -R | tail -n +10000 | tr '\n' '\0' | xargs -0 rm

trpermettra à sort et tail de travailler sur des listes avec \nau lieu de \0.

Luca Di Liello
la source
-2

Le plus simple pourrait être de rm -rf le répertoire, puis réexécutez le script de génération de données tout en veillant à ne pas s'exécuter trop longtemps.

Lars Poulsen
la source
Ce n'est pas ce que le PO a demandé. Peut-être que ce n'est pas possible.