Comment supprimer plusieurs fichiers avec un préfixe et un suffixe communs?


21

J'ai de nombreux fichiers nommés

sequence_1_0001.jpg  
sequence_1_0002.jpg  
sequence_1_0003.jpg  
...

et fichiers nommés

sequence_1_0001.hmf  
sequence_1_0002.hmf  
sequence_1_0003.hmf  
...

et fichiers nommés

sequence_2_0001.jpg  
sequence_2_0002.jpg  
sequence_2_0003.jpg  
...

et

sequence_2_0001.hmf  
sequence_2_0002.hmf  
sequence_2_0003.hmf  
...

Je veux juste supprimer les fichiers qui commencent par «séquence_1» et se terminent par «.hmf», mais je ne veux pas les supprimer un par un, car il y a des milliers de fichiers. Comment puis-je spécifier à la commande rm que je veux supprimer tout ce qui commence par le préfilx 'séquence_1' et se termine par '.hmf'?

Je travaille actuellement avec un système Linux RedHat, mais j'aimerais savoir comment le faire sur d'autres distributions également.

Réponses:


28
rm sequence_1*.hmf

supprime les fichiers commençant par sequence_1et se terminant par .hmf.


Globbing est le processus dans lequel votre shell prend un modèle et le développe dans une liste de noms de fichiers correspondant à ce modèle. Ne le confondez pas avec les expressions régulières, ce qui est différent. Si vous passez la plupart de votre temps bash, le Wiki Wooledge a une bonne page sur la globalisation (extension de nom de chemin) . Si vous voulez une portabilité maximale, vous voudrez également lire la spécification POSIX sur la correspondance de modèle .


Dans le cas peu probable où vous rencontrez une erreur "Argument list too long" , vous pouvez jeter un œil à BashFAQ 95 , qui résout ce problème. La solution de contournement la plus simple consiste à décomposer le motif glob en plusieurs morceaux plus petits, jusqu'à ce que l'erreur disparaisse. Dans votre cas, vous pourriez probablement vous en sortir en divisant la correspondance par les chiffres de préfixe 0 à 9, comme suit:

for c in {0..9}; do rm sequence_1_"$c"*.hmf; done
rm sequence_1*.hmf  # catch-all case

Il s'agit d'un travail très intelligent autour de l'erreur «liste d'arguments trop longue». Dans mon cas, j'ai vingt mille fichiers, donc je suppose que je devrais utiliser une boucle for à partir de 0, .., 20. Droite?
Paul

@Paul Oui, divisez simplement la liste en autant de morceaux que vous le souhaitez, bien qu'à un moment donné, l' findapproche devienne plus facile que de deviner et de vérifier.
jw013

14

Bien que la réponse de jw013 soit correcte par rapport à la globalisation, cette commande peut échouer si vous avez des milliers de correspondances: la ligne de commande développée rm sequence_1_0001.hmf sequence_1_0002.hmf ...générée par le shell peut simplement être trop grande.

Comme Dom l'a suggéré, vous pouvez également utiliser l' -deleteoption avec find:

find . -maxdepth 1 -type f -name 'sequence_1*.hmf' -delete

Les deux -maxdepthet -delete, bien qu'ils ne soient pas dans la norme POSIX, sont assez courants dans les findimplémentations dans la nature. Les distributions Linux utilisent généralement GNU find, qui prend certainement en charge ces options.


2
Si vous le pouvez, utilisez l'option -delete pour trouver, il ne se déroule pas pour chaque fichier ...
Dom

Ajouté, bravo. Il semble que cela -deletedevrait être pris en charge sur les systèmes GNU et BSD récents , alors qu'il -print0est uniquement GNU. Il est donc probablement plus portable aussi (bien que cela ne devrait pas faire de différence pour l'OP).
inutile

Au moins OS X trouve -print0, mais il n'est pas inclus dans POSIX.
Lri

5
rm sequence_1_{0000..0999}.hmf
rm sequence_1_{1000..1999}.hmf
rm sequence_1_{2000..2999}.hmf
...

fonctionnerait aussi dans Bash.


L'expansion de l'accolade nécessite bash, et la forme zéro rembourrée a besoin de la version 4, je crois.
jw013
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.