Je veux supprimer des fichiers dans $DIR_TO_CLEAN
plus anciens que $DAYS_TO_SAVE
jours. Facile:
find "$DIR_TO_CLEAN" -mtime +$DAYS_TO_SAVE -exec rm {} \;
Je suppose que nous pourrions append un indicateur de -type f
ou un indicateur -f
pour rm
, mais je voudrais vraiment compter le nombre de fichiers supprimés.
Nous pourrions le faire naïvement:
DELETE_COUNT=`find "$DIR_TO_CLEAN" -mtime +$DAYS_TO_SAVE | wc -l` find "$DIR_TO_CLEAN" -mtime +$DAYS_TO_SAVE -exec rm {} \;
Mais cette solution laisse beaucoup à désirer. Outre la duplication de commandes, cet extrait surestime le compte si rm
n’a pas pu supprimer un fichier.
Je suis tout à fait à l’aise avec la redirection, les tuyaux (y compris ceux nommés), les sous- xargs
, xargs
, tee
, etc., mais j’ai hâte d’apprendre de nouveaux trucs. Je voudrais une solution qui fonctionne à la fois sur bash et ksh.
Comment comptez-vous le nombre de fichiers supprimés par find
?
Vous pouvez simplement utiliser bash dans find:
find "$DIR_TO_CLEAN" -mtime +$DAYS_TO_SAVE -exec bash -c 'printf "Total: %d\n" $#; rm "$@"' _ {} +
Bien sûr, cela peut appeler bash -c …
plus d’une fois si le nombre de fichiers trouvés est plus grand que MAX_ARGS, et cela peut aussi surestimer le compte en cas d’échec de rm. Mais résoudre ces problèmes devient désordonné:
find "$DIR_TO_CLEAN" -mtime +$DAYS_TO_SAVE -exec bash -c 'printf "count=0; for f; do rm "$f" && (( count++ )); done; printf "Total: %d\n" $count' _ {} +
Cette solution pour éviter les limites MAX_ARGS évite toute recherche. Si vous en avez besoin, vous devrez utiliser la globalisation récursive, disponible uniquement dans les nouveaux shells. ( globstar
est une fonctionnalité de bash 4.)
shopt -s globstar # Assume DAYS_TO_SAVE reformatted to how touch -m expects it. (Exercise for the reader.) touch -m "$DAYS_TO_SAVE" referencefile count=0 for file in "$DIR_TO_CLEAN/"**/*; do if [[ referencefile -nt "$file" ]]; then rm "$file" && (( count++ )) fi done printf 'Total: %d\n' "$count"
Voici une approche utilisant find avec printf (la recherche ssortingctement conforme n’a pas printf, mais vous pouvez utiliser printf comme un utilitaire autonome dans ce cas).
find "$DIR_TO_CLEAN" -type -f -mtime "+$DAYS_TO_SAVE" -exec rm {} \; -printf '.' | wc -c find "$DIR_TO_CLEAN" -type -f -mtime "+$DAYS_TO_SAVE" -exec rm {} \; -exec printf '.' \; | wc -c
-exec
et -exec
pour une solution canalisée:
find "$DIR_TO_CLEAN" -type f -mtime +$DAYS_TO_SAVE -print0 \ | awk -v RS='\0' -v ORS='\0' '{ print } END { print NR }' \ | xargs -0 rm
Utiliser awk
pour compter les correspondances et les transmettre à rm
.
kojiro m’a fait comprendre que la solution ci-dessus ne compte pas le taux de réussite / échec de rm
. Comme awk
a des problèmes avec les fichiers mal nommés, je pense que la solution suivante pourrait être meilleure:
find "${DIR_TO_CLEAN?}" -type f -mtime +${DAYS_TO_SAVE?} -print0 | ( success=0 fail=0 while read -rd $'\0' file; do if rm "$file" 2> /dev/null; then (( success++ )) else (( fail++ )) fi done echo $success $fail )