Comment lister les fichiers de plus d'un jour avec «2015» dans le nom de fichier?

11

Je souhaite répertorier tous les fichiers journaux qui n'appartiennent pas à aujourd'hui et uniquement les fichiers qui contiennent 2015leurs noms.

Ce sont les commandes que j'ai essayées:

find . -name 2015 -mtime +1 -exec  ls -ltrh  {} \;
find . -name *2015* -mtime +1 -exec  ls -ltrh  {} \;

La sortie des deux n'est rien, mais quand même, les fichiers sont là. Quelque chose ne va pas avec ces commandes, et je ne comprends pas quoi. Toute aide serait appréciée.

rɑːdʒɑ
la source
La findpartie me semble bien, mais j'ai également eu des problèmes avec le -execparamètre. Je n'ai pas pu faire fonctionner ça non plus. (J'essayais de déplacer tous les fichiers jpg d'un dossier vers son répertoire parent - et j'ai fini par le faire manuellement ...)
Byte Commander
2
Vous voudrez peut-être jeter un œil à Pourquoi find -mtime +1 ne renvoie-t-il que les fichiers de plus de 2 jours?
steeldriver
@steeldriver Je pense que c'est vraiment ce qui ne va pas ici, car s'il y avait des fichiers dans le répertoire actuel avec 2015leur nom (l'autre lacune évidente de la façon dont la commande est écrite), je pense qu'il y aurait une sorte de sortie. Vous voudrez donc peut-être publier une réponse à ce sujet.
Eliah Kagan

Réponses:

18

La commande find . -name '*2015*' -mmin +1440 -lsfera probablement ce que vous voulez. Voir ci-dessous pour plus de détails.

Votre première commande avait -name 2015. Cela n'a pas fonctionné car il ne trouve que les fichiers dont les noms sont exacts 2015 , sans autres caractères.

Votre deuxième commande, a find . -name *2015* -mtime +1 -exec ls -ltrh {} \;peut-être échoué pour plusieurs raisons:

1. Les* caractères non entre guillemets sont développés par le shell, puis transmis à find.

S'il y a des fichiers directement contenus dans le répertoire courant (celui dans lequel vous vous trouvez lorsque vous avez exécuté cette find ...commande) dont les noms contiennent 2015(et ne commencent pas par un .), le shell s'est développé *2015*dans une liste de ces noms de fichiers, puis passé cette liste comme arguments find. Ce n'est pas ce que vous voulez - au lieu de cela, vous voulez passer *2015*littéralement comme un argument à rechercher, de sorte que find, et non le shell, puisse trouver les fichiers qui lui correspondent.

Pour résoudre ce problème, citez *2015*. Il existe trois façons courantes de procéder:

  • '*2015*'(c.-à-d. find . -name '*2015*' -mtime +1 -exec ls -ltrh {} \;)
  • "*2015*"(c.-à-d. find . -name "*2015*" -mtime +1 -exec ls -ltrh {} \;)
  • \*2015\*(c.-à-d. find . -name \*2015\* -mtime +1 -exec ls -ltrh {} \;)

Je vous suggère de l'écrire avec des guillemets simples comme '*2015*', parce que:

Mais dans ce cas, cela n'a pas vraiment d'importance. 'et les "deux traitent *la même chose et l'expression n'est pas assez compliquée pour être \citée, ce qui la rend difficile à comprendre.

2. -mtime +1sélectionne uniquement les fichiers modifiés il y a deux jours ou plus .

Comme man finddit:

       Numeric arguments can be specified as

       +n     for greater than n,

       -n     for less than n,

       n      for exactly n.
       -mtime n
              File's data was last modified n*24 hours ago.  See the  comments
              for -atime to understand how rounding affects the interpretation
              of file modification times.
       -atime n
              File was last accessed n*24 hours ago.  When  find  figures  out
              how  many  24-hour  periods  ago the file was last accessed, any
              fractional part is ignored, so to match -atime +1, a file has to
              have been accessed at least two days ago.

Supposons qu'un fichier a été modifié il y a 47 heures. Pour déterminer le nombre de périodes de 24 heures, findarrondissez vers le bas : il s'agit d' une période de 24 heures. Mais -mtime +1ne correspond qu'aux fichiers dont les délais de modification sont strictement supérieurs à une période de 24 heures. Ainsi, les fichiers d'hier ne correspondent pas.

Voir Pourquoi find -mtime +1 renvoie-t-il uniquement les fichiers de plus de 2 jours? pour plus d'informations, comme suggéré par steeldriver .

Pour rechercher les fichiers modifiés pour la dernière fois il y a plus de 24 heures , je suggère plutôt de le spécifier comme il y a 1440 minutes avec -mmin +1440:

find . -name '*2015*' -mmin +1440 -exec ls -ltrh {} \;

Certains lecteurs se demandent peut-être pourquoi je n'ai pas cité {}. Certaines personnes citent {}pour rappeler aux humains que ce n'est pas une expression pour l' expansion de l'orthèse . Les coques de style Bourne (comme bash ) n'ont pas besoin {}de rien à l'intérieur pour être citées. Peut-être que certains shell de style non Bourne le traitent spécialement; c'est peut-être pourquoi certains utilisateurs le citent. Mais il y a aussi une idée fausse selon laquelle il faut parfois citer {}pour -execgérer correctement les noms de fichiers avec des espaces. C'est faux: avec {}ou '{}', findobtient les mêmes arguments, car le shell supprime les guillemets avant de passer '{}'àfind. Pour contrer cette idée fausse, je ne cite pas {}, mais c'est une question de style - si vous préférez {}documenter comment la coque ne traite pas {et }spécialement, c'est bien.

Je vous recommande également de modifier votre lscommande, ou (comme Muru l'a suggéré ) de la remplacer par findl' -lsaction de. ls -ltrhne fait probablement pas ce que vous envisagez car il est exécuté séparément pour chaque fichier trouvé et donc les indicateurs -tet -r, qui spécifient le tri, ne sont pas pertinents.

Bien que la sortie soit formatée un peu différemment qu'avec ls -l, l'utilisation -lsest plus simple et plus facile.

find . -name '*2015*' -mmin +1440 -ls

Ou si vous décidez que vous n'avez vraiment besoin que de répertorier les noms des fichiers (y compris leurs chemins d'accès, par rapport à .), vous pouvez simplement spécifier aucune action, ce qui entraîne l'utilisation de l' -printaction par défaut :

find . -name '*2015*' -mmin +1440
Eliah Kagan
la source
1
Belle réponse complète! au moins avec GNU find, il y a aussi la newerXYsyntaxe, qui accepte par exemple les arguments de calendrier -newermt 'yesterday'et! -newermt 'yesterday'
steeldriver
Vous savez quoi ? Vous êtes génial. @ Eliah Kagan
rɑːdʒɑ
Merci Stell Driver, c'est de très bonnes informations sur le lien à connaître. Mais dans mon cas, car il s'agit du journal des applications, les anciens fichiers n'ont aucun moyen d'être modifiés. Merci encore
rɑːdʒɑ
2

Citez l'expression et je vous suggère de citer également les crochets

find . -name "2015" -mtime +1 -exec  ls -ltrh  '{}' \;

ou

find . -name "*2015*" -mtime +1 -exec  ls -ltrh  '{}' \;

vous n'avez pas besoin de transmettre les fichiers que vous trouvez à ls

find . -name "*2015*" -mtime +1
Panthère
la source
Peut-être restreindre l'utilisation -type f? Et s'il lsdoit être utilisé, suggérez d'utiliser -ls.
muru
1
bien sûr, toutes les bonnes suggestions. Je ne suis pas sûr de ce que l'OP veut et je crois que la source du problème est le manque de guillemets autour du modèle de recherche "-name".
Panther
2

Dans zsh , vous pouvez utiliser des qualificatifs glob (il s'agit d'une fonctionnalité zsh unique, non disponible dans d'autres shells tels que bash).

ls -ltr *2015*(m+1)

Cela répertorie uniquement les fichiers du répertoire actuel; pour parcourir les répertoires récursivement , utilisez

ls -ltr **/*2015*(m+1)

Avec find, -name 2015ne trouve que les fichiers dont le nom est exactement 2015. -name *2015*ne fonctionne que s'il n'y a pas de fichiers dont le nom contient 2015dans le répertoire courant, car le shell développe le modèle *2015*avant qu'il findsoit appelé. Vous devez citer le modèle:

find -name '*2015*' -mtime +1 …

Notez que les deux find -mtime +1et zsh *(m+1)trouvent des fichiers qui ont au moins 48 heures , pas des fichiers plus anciens qu'aujourd'hui. Le signe plus signifie «strictement supérieur à» et le nombre de jours est arrondi vers le bas. Pour rechercher des fichiers datant d'au moins 24 heures, utilisez -mtime +0ou (m+0).

Si vous souhaitez rechercher les fichiers qui ont été modifiés hier ou avant , vous pouvez utiliser findavec le -newermtprédicat :

find -name '*2015*' ! -newermt 'today 0:00' …

Il n'y a pas de moyen vraiment pratique de faire ce test dans zsh.

Gilles 'SO- arrête d'être méchant'
la source