Quelle est la bonne syntaxe find -exec

10

Je voulais supprimer des fichiers supérieurs à 2 Mo dans un dossier spécifique. J'ai donc couru:

find . -size +2M

Et j'ai une liste de deux fichiers

./a/b/c/file1

./a/f/g/file2

Je lance donc:

find . -size +2M -exec rm ;

et je reçois le message d'erreur Find: missing argument to -exec

Je vérifie la syntaxe dans la page de manuel et ça dit -exec command ;

Alors au lieu de ça j'essaye

find . -size +2M -exec rm {} +

Et il fonctionne. Je comprends que le {} lui fait exécuter la commande comme rm file1 file2au lieu de rm file1; rm file2;.

Alors pourquoi le premier n'a-t-il pas fonctionné?

RÉPONSE:

Je suppose que je devais juste RTFM quelques fois pour enfin comprendre ce qu'il disait. Même si le premier exemple ne montre pas {}, les accolades sont obligatoires dans tous les cas. Et puis ajoutez \; ou + selon la méthode souhaitée. Ne vous contentez pas de lire l'en-tête. Lisez également la description. Je l'ai.

Safado
la source

Réponses:

16

Vous pouvez utiliser n'importe lequel des formulaires:

find . -size +2M -exec rm {} +

find . -size +2M -exec rm {} \;

Le point-virgule doit être échappé!

Khaled
la source
10
-exec rm {} \;

vous pouvez utiliser .. l'homme trouve

-exec command ;
              Execute command; true if 0 status is returned.  All following arguments to find are taken to be arguments to the  command  until
              an  argument  consisting of `;' is encountered.  The string `{}' is replaced by the current file name being processed everywhere
              it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find.  Both of  these
              constructions  might  need  to  be escaped (with a `\') or quoted to protect them from expansion by the shell.  See the EXAMPLES
              section for examples of the use of the -exec option.  The specified command is run once for each matched file.  The  command  is
              executed  in  the  starting directory.   There are unavoidable security problems surrounding use of the -exec action; you should
              use the -execdir option instead.

       -exec command {} +
              This variant of the -exec action runs the specified command on the selected files, but the command line is  built  by  appending
              each  selected file name at the end; the total number of invocations of the command will be much less than the number of matched
              files.  The command line is built in much the same way that xargs builds its command  lines.   Only  one  instance  of  `{}'  is
              allowed within the command.  The command is executed in the starting directory.
dSoultanis
la source
1
Ah ok. Je suppose que je devais juste RTFM quelques fois pour enfin comprendre ce qu'il disait. Même si le premier exemple ne montre pas {}, les accolades sont obligatoires dans tous les cas. Et puis ajoutez \; ou + selon la méthode souhaitée. Je l'ai.
Safado
2

Par souci d'efficacité, il est généralement préférable d'utiliser xargs:

$ find /path/to/files -size +2M -print0 | xargs -0 rm
EEAA
la source
1
Pas vraiment. Comme le dit l'entrée du Guide sur le wiki de Greg: le + (au lieu de;) à la fin de l'action -exec indique à find d'utiliser une fonctionnalité interne de type xargs qui fait que la commande rm n'est invoquée qu'une seule fois pour chaque bloc de fichiers, au lieu d'une fois par fichier.
adaptr
Ahh, intéressant. J'utilise find + xargs depuis des années et des années, et je n'ai jamais connu l'opérateur +. Merci d'avoir fait remarquer cela!
EEAA
Je peux recommander sans réserve le wiki de Greg; cet homme en sait plus sur bash et le jeu d'outils GNU que je ne pourrais jamais espérer en apprendre; il est sûr de dire que j'ai appris plus sur l'utilisation de bash depuis que j'ai commencé à le lire que pendant toutes les années précédentes.
adaptr
2
Qui est Greg et où puis-je trouver son wiki?
Safado
@Safado Je pense que c'est celui-ci: mywiki.wooledge.org
Enrico Stahn
0

Je n'utiliserais pas du tout -exec pour cela. find peut également supprimer les fichiers eux-mêmes:

find . -size +2M -delete

(c'est probablement un GNUisme cependant, je ne sais pas si vous le trouveriez dans une recherche non gnu)

Ragoût
la source
Y a-t-il une raison derrière cela ou est-ce simplement une préférence personnelle?
Safado
ne trouve que les appels unlink (2) lui-même et n'a pas à débiter de nouveaux processus pour effectuer la suppression. Ce serait beaucoup plus efficace. C'est aussi beaucoup plus lisible.
ragoût
0

Comme documenté, -exec requiert {} comme espace réservé pour la sortie de find.

Le guide définitif pour utiliser les outils bash et GNU est ici

Comme vous pouvez le voir, il montre explicitement la deuxième commande que vous avez utilisée comme exemple.

adaptr
la source