Trouver -exec dry run?

Dec 27 2020

Existe-t-il un moyen de voir quel find . -exec somecommand {} \;serait le résultat d'un a avec des substitutions, sans réellement exécuter les commandes? Comme un essai à sec (ou un essai ou une impression)?

Par exemple, supposons que j'ai la structure de fichiers suivante:

/a/1.txt
/a/2.txt
/a/b/3.txt

Existe-t-il un moyen de tester à find . type f -exec rm {} \;partir du arépertoire de sorte que la sortie soit imprimée sur stdout mais non exécutée, par exemple:

rm 1.txt
rm 2.txt
rm b/3.txt

Note de mise à jour : rmest juste un exemple de commande, je suis intéressé par le cas général

Réponses

18 rAlen Dec 27 2020 at 07:10

Vous pouvez courir echo rmau lieu derm

find . type f -exec echo rm {} \;

En outre, finda l' -deleteoption pour supprimer les fichiers qu'il trouve

3 l0b0 Dec 27 2020 at 07:28

Pour plus rmprécisément, vous n'avez pas besoin -exec: exécutez simplement find . -type fpour lister et ajoutez -deletepour supprimer les fichiers répertoriés par la commande précédente (en excluant évidemment tout fichier correspondant créé / supprimé entre-temps).

De plus, pour des commandes comme celles rmqui prennent un nombre arbitraire d'arguments, vous voudrez les remplacer \;par +pour exécuter le moins de commandes possible.

2 CharlesDuffy Dec 28 2020 at 00:38

C'est un peu une bouchée, mais contrairement aux approches utilisant echo, le code ci-dessous génère du code que vous pouvez exécuter dans votre shell sans aucune modification pour obtenir le résultat correct, même lorsque vos noms de fichiers contiennent des guillemets, des espaces, des métacaractères du shell, etc.

printcmd() { printf '%q ' "$@"; printf '\n'; } find . -exec bash -c "$(declare -f printcmd); "'printcmd "$@"' _ \
  somecommand {} \;

Notez que la chaîne que nous ajoutons au début de notre -execargument est précisément bash -c "$(declare -f printcmd); "'printcmd "$@"' _- le se $(declare -f printcmd)développe au code de la fonction; après cela, nous appelons en fait la fonction avec des arguments $1et en avant, et la plaçons _comme espace réservé pour $0.

Vous pouvez remplacer zshou à la kshplace de bash, si vous voulez que la sortie soit échappée pour ce shell.