web-dev-qa-db-fra.com

Comment trouver des fichiers entre deux dates en utilisant "find"?

J'ai un compte de messagerie qui a dépassé les 60 Go de courriels et, actuellement, j'ai beaucoup de difficulté à utiliser un client de messagerie pour archiver les courriels de l'année dernière (2011).

Par l'intermédiaire du terminal, j'essaye d'utiliser trouver pour localiser les fichiers entre le 2011-01-01 et le 2011-12-31, mais sans succès.

Comment trouver des fichiers entre deux dates?

Le cas échéant, l’objectif final sera un lot qui déplacera chaque fichier trouvé, correspondant à l’intervalle de dates, dans un dossier.

20
Zuul

Vous pouvez utiliser ce script:

#!/bin/bash
for i in $(find Your_Mail_Dir/ -newermt "2011-01-01" ! -newermt "2011-12-31"); do
  mv $i /moved_emails_dir/
done

Bash trouve des fichiers entre deux dates:

find . -type f -newermt 2010-10-07 ! -newermt 2014-10-08

Renvoie une liste des fichiers dont l'horodatage est postérieur au 2010-10-07 et avant le 2014-10-08.

Bash trouve des fichiers d'il y a 15 minutes jusqu'à maintenant:

find . -type f -mmin -15

Renvoie une liste de fichiers qui ont un horodatage après 15 minutes mais avant maintenant.

Bash trouve des fichiers entre deux horodatages:

find . -type f -newermt "2014-10-08 10:17:00" ! -newermt "2014-10-08 10:53:00"

Renvoie les fichiers dont l'horodatage est compris entre 2014-10-08 10:17:00 et 2014-10-08 10:53:00

39
Eric Leschinski

Déplacement des fichiers et invite l'utilisateur lorsqu'il y a des noms en double:

Comme le montrent les réponses de Subv3rsion et de Eric Leschinski , le prédicat -newermt sélectionne les fichiers modifiés plus récemment que la date (et l'heure facultative) spécifiée comme son opérande. Pour trouver des fichiers

  • n'importe où dans srcdir (c'est-à-dire y compris ses sous-répertoires, leurs sous-répertoires, etc.)
  • dernière modification en septembre 2014 (par exemple)
  • et déplacez-les vers destdir

...tu peux courir:

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -i {} destdir/ \;

Dans une expression -exec, find transmet le nom de fichier trouvé à la place de {}. ; indique à -exec que la commande à exécuter et ses arguments ont tous été fournis (dans le cas où les expressions suivantes sont passées pour rechercher après les arguments de ce prédicat -exec donné - voir ci-dessous pour un exemple.). ; doit être échappé en tant que \; afin qu'il ne soit pas interprété spécialement par le shell. (Sans \, ; mettrait fin à la commande entière find et fonctionnerait comme une nouvelle ligne. Même si cette commande find n'a rien après cette expression -exec, le fait de ne pas transmettre l'argument ; reste une erreur de syntaxe.)

Si vous souhaitez simplement répertorier les fichiers - ce qui est conseillé si vous n'êtes pas sûr du mode de stockage des anciens e-mails ou des fichiers pouvant être présents - omettez -exec et tout ce qui se trouve à droite. (Pour les courriels, les courriels de dates différentes sont souvent stockés dans le fichier même; pour les personnes se trouvant dans la situation décrite dans la question, je vous recommande de rechercher comment ils sont stockés avant de déplacer des fichiers.) Si vous le souhaitez. pour imprimer leur nom et le déplacer, ajoutez -print avant -exec.

mv -i demande à chaque fois qu'un fichier est écrasé à la destination, comme cela pourrait arriver si:

  • un fichier du même nom existe depuis une sauvegarde précédente, o
  • un fichier du même nom mais provenant d'un sous-répertoire différent de srcdir a déjà été déplacé au cours de la même opération find, o
  • (moins probable) un fichier du même nom a été créé quelque part dans srcdir au cours de la même opération find, après le déplacement de l'original mais suffisamment tôt pour être trouvé une fois que find a traversé un sous-répertoire différent.

Autres façons d'invoquer rm:

Vous avez d'autres options pour gérer les fichiers avec des noms en double.

  • Sans -i (c'est-à-dire mv {} destdir/), mv ne demanderait généralement pas d'approbation, mais le ferait si le fichier de destination était en lecture seule. (mv peut même parfois écraser un fichier en lecture seule, par exemple si l'utilisateur qui l'exécute possède le fichier.)
  • Si vous ne voulez même pas ce degré d'interactivité et que vous voulez que mv écrase toujours les fichiers de même nom, utilisez mv -f.
  • Si, au contraire, vous voulez ignorer les fichiers source alors qu'il existe déjà un fichier de destination du même nom, utilisez mv -n.
  • mv accepte les indicateurs -b et --backup pour renommer automatiquement les fichiers de même nom qui existent déjà dans la destination. Par défaut, ~ est ajouté pour générer le nom de la sauvegarde. Si un fichier portant le nom et un fichier avec le nom de la sauvegarde existent déjà sur la destination, le fichier de sauvegarde est écrasé. Cette valeur par défaut peut être remplacée par les options passées lors de l'appel de mv et par les variables d'environnement. Voir man mv pour plus de détails et l'exemple ci-dessous.

Déplacement des fichiers et création de sauvegardes en cas de noms dupliqués:

Pour déplacer tous les fichiers, sauvegardez les fichiers avec des noms en double avec un suffixe ~ et utilisez des suffixes numérotés .~n~ lorsque des fichiers .~ existent déjà (afin d'éviter tout écrasement), exécutez:

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv --backup=existing {} destdir/ \;

Si vous avez ignoré des fichiers avec des noms en double et souhaitez savoir lesquels:

Si vous utilisez mv -n et souhaitez savoir quels fichiers n'ont pas été déplacés car il y avait un autre fichier portant le même nom, le meilleur moyen consiste probablement à exécuter à nouveau la commande find d'origine, sans -exec et tout à droite de celle-ci. Cela affichera leurs noms.
Il imprimera également les noms des fichiers correspondants créés depuis l'exécution de la commande find .... -exec ... d'origine, mais pour cette application, il n'y en aura généralement aucun, car vous recherchez des fichiers avec des temps de modification anciens. Il est possible de donner à un fichier un horodatage de modification plus ancien que son âge réel, avec touch et d'autres mécanismes, mais cela ne semble pas devoir se produire dans ce cas à votre insu.

Savoir immédiatement que les fichiers sont ignorés en raison de noms en double:

mv -n ne fait pas de rapport, ni ne retourne de caractères spéciaux code de sortie , lorsqu'il ne déplace pas de fichier. Donc, si vous souhaitez être immédiatement informé des fichiers ignorés pendant l'exécution de find, vous devrez effectuer une étape distincte à cet effet. Une façon est:

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -n {} destdir/ \; \
    -exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} destdir \; 

Quelques considérations techniques probablement mineures: Ceci avertit incorrectement si mv ne parvient pas à copier un fichier pour une raison différente de celle existant à la destination et quitte signale le succès. Cela semble peu probable, mais je ne suis pas sûr que ce soit impossible. Il est également potentiellement victime d'une condition de concurrence : il avertirait en l'absence d'erreur réelle si un nouveau fichier du même nom était créé au même endroit très peu de temps après l'ancien fichier. a été déplacé et avant le contrôle pour voir si elle a été supprimée. (Compte tenu de l'application, je doute que l'un ou l'autre problème se produise réellement.) Il pourrait être réécrit pour vérifier la destination avant ​​déplacer le fichier au lieu de après: la condition de concurrence porterait alors sur les fichiers de destination nouvellement créés. des fichiers source. Et tandis que les erreurs et avertissements signalés par find ou mv (ou [, bien qu'il ne devrait en exister aucune), seront écrits en erreur standard , notre avertissement ...skipped (exists in... est écrit en sortie standard =. Normalement, les deux apparaissent sur votre terminal, mais cela peut être important si vous utilisez un script.

J'ai divisé cette commande en deux lignes pour faciliter la lecture. Il peut être exécuté de cette façon ou vous pouvez supprimer le \ et la nouvelle ligne (c'est-à-dire le saut de ligne).

Comment fonctionne cette commande find?

Les prédicats find peuvent être tests (comme -type et -newermt), utilisés pour leurs valeurs de retour, ou actions (comme -print et -exec), qui sont souvent = utilisé pour leurs effets secondaires.

Quand aucun opérateur (comme -a pour et, -o pour o) n'est fourni entre les expressions, -a est impliqué. find emploie évaluation de court-circuit pour and et o. pq (c'est-à-dire p -a q) n'est vrai que si les expressions p et q sont vraies, donc q n'a pas besoin d'être évalué si - p est faux. Bien que nous n'y pensions pas souvent en ces termes, c'est pourquoi les tests doivent être vrais pour que les actions ou les tests ultérieurs soient évalués. Par exemple, supposons que find entre dans un répertoire. Il évalue -type f à false afin qu'il puisse tout ignorer par la suite.

Comme les tests, les actions sont évaluées comme vraies ou fausses. De cette manière, -exec indique si la commande exécutée a quitté le signalement de la réussite (true) ou de l'échec (false). Nous avons cette chaîne d'expressions -exec liées à implicite and:

-exec mv -n {} destdir/ \; -exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} destdir \;

Cela tente de déplacer le fichier et, si mv signale un échec, s’arrête. Nous ne voulons pas vous prévenir si un fichier est correctement ignoré si un autre problème était la raison pour laquelle il n'a pas été déplacé.

Mais s'il réussit, il s'exécute alors la commande [ . Comme find, [ prend en charge son propre type d'expressions transmises en tant qu'arguments. [ -f {} ] vérifie si l'opérande après -f (qui lui a été transmis par find à la place de {}) existe (et est un fichier normal), et renvoie soit vrai/succès, soit faux/échec.
(Les statuts de sortie de nombreuses commandes sont mieux interprétés comme indiquant un succès ou un échec, mais le statut d'existence de [ est généralement interprété comme étant vrai ou faux.)

Si [ a renvoyé la valeur false, alors le fichier est parti, il a donc été déplacé, il n'y a donc rien à faire. Mais si [ a renvoyé la valeur false, le fichier est toujours là. Ensuite, find évalue la prochaine expression -exec, qui affiche le message d'avertissement.

Lectures complémentaires

9
Eliah Kagan