50 votes

Supprimer tous les fichiers d'un répertoire, à l'exception de ceux portant l'extension pdf

J'ai un répertoire qui contient les éléments suivants :

x.pdf
y.zip
z.mp3
a.pdf

Je souhaite supprimer tous les fichiers à l'exception de x.pdf y a.pdf . Comment faire cela à partir du terminal ? Il n'y a pas de sous-répertoire, donc pas besoin de récursivité.

3voto

Nathan Long Points 145

Soyez prudent et composez : utilisez xargs

Voici une approche que j'aime bien, parce qu'elle me permet d'être très prudent : composez un moyen d'afficher uniquement les fichiers que je veux supprimer, puis envoyez-les à rm en utilisant xargs . Par exemple :

  • ls me montre tout
  • ls | grep pdf m'indique les fichiers que je souhaite conserver. Hmm.
  • ls | grep -v pdf montre le contraire : tous les sauf ce que je veux garder. En d'autres termes, il affiche la liste des éléments que je souhaite supprimer. Je peux le confirmer avant de faire quoi que ce soit de dangereux.
  • ls | grep -v pdf | xargs rm envoie exactement cette liste à rm pour suppression

Comme je l'ai dit, je l'apprécie principalement pour la sécurité qu'il offre : aucun accident n'est possible. rm * pour moi. Deux autres avantages :

  • Il est composable ; vous pouvez utiliser ls ou find pour obtenir la liste initiale, comme vous le préférez. Vous pouvez utiliser tout ce que vous voulez dans le processus de réduction de cette liste. grep , certains awk ou autre. Si vous deviez supprimer uniquement les fichiers dont le nom contient une couleur, vous pourriez procéder de la même manière.
  • Vous pouvez utiliser chaque outil pour son objectif principal. Je préfère utiliser find pour trouver et rm pour la suppression, au lieu d'avoir à se rappeler que find accepte un -delete drapeau. Et si vous faites cela, vous pouvez composer d'autres solutions ; peut-être qu'au lieu de rm vous pourriez créer un trash qui déplace le fichier vers la corbeille (ce qui permet de ne pas l'effacer) et de l'acheminer vers cette commande au lieu de la commande rm . Il n'est pas nécessaire d'avoir find soutiennent cette option, vous n'avez qu'à y ajouter un tuyau.

アップデート

Voir les commentaires de @pabouk pour savoir comment modifier cela pour gérer certains cas particuliers, comme les sauts de ligne dans les noms de fichiers, les noms de fichiers comme my_pdfs.zip , etc.

3voto

mic_e Points 131

Je résous généralement ces problèmes à partir de l'interpréteur interactif Python :

mic@mic ~ $ python
>>> import os
>>> for f in os.listdir('.'):
...   if not f.endswith('.pdf'):
...     os.remove(f)

Il peut être plus long qu'une simple phrase avec find ou xargs Mais il est extrêmement résistant et je sais exactement ce qu'il fait, sans avoir à faire de recherches au préalable.

2voto

Edward Torvalds Points 7511

Une meilleure réponse (par rapport à ma réponse précédente) à cette question serait l'utilisation de la puissante fonction file commandement.

$ file -i abc.pdf
abc: application/pdf; charset=binary

maintenant votre problème :

cd <the directory you want to search in>
for var in ./*
do
  if file -i "$var" | grep -q 'application/pdf\;'
    then
    echo "$var"
  fi
done

Le travail de for donne les fichiers du répertoire courant sous la forme d'une variable $var . if-then donne les noms des fichiers pdf en prenant l'état de sortie de la commande 0 de file -i "$var" | grep -q 'application/pdf\;' il donnera le statut de sortie de 0 uniquement s'il trouve des fichiers pdf.

1voto

rm $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')

Attention ! Mieux vaut essayer d'abord

ls -l $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')

1voto

shalomb Points 241
rm -i -- !(*@(a|x).pdf)

En lecture seule, supprimer tous les fichiers qui ne sont pas a.pdf ou x.pdf .

Pour ce faire, il faut utiliser deux globes étendus, le globule extérieur et le globule intérieur. !() pour annuler le glob contenu, ce qui nécessite que le glob corresponde à un ou plusieurs des éléments suivants a ou x avant l'entrée en vigueur de la .pdf suffixe. Voir aussi glob#extglob .

$ ls -a
.dotfile1 .dotfile2 a.pdf x.pdf y.zip z.mp3

$ echo -- !(a.pdf)
-- x.pdf y.zip z.mp3

$ echo -- !(x.pdf)
-- a.pdf y.zip z.mp3

$ echo -- !(a.pdf|x.pdf)
-- y.zip z.mp3

$ echo -- !(@(a|x).pdf)   # NOTE.that this matches the .dotfiles* as well
-- . .. .dotfile1 .dotfile2 y.zip z.mp3

$ echo -- !(*@(a|x).pdf)  # but this doesn't
-- y.zip z.mp3

$ echo rm -i -- !(*@(a|x).pdf)
rm -i -- y.zip z.mp3

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X