comment puis-je vérifier dans bash si un fichier a été créé il y a plus de x fois?

106

Je veux vérifier dans linux bash si un fichier a été créé il y a plus de x fois.

disons que le fichier s'appelle text.txt et que la durée est de 2 heures.

 if [ what? ]
 then
     echo "old enough"
 fi
flybywire
la source

Réponses:

138

Seulement pour le temps de modification

if test `find "text.txt" -mmin +120`
then
    echo old enough
fi

Vous pouvez utiliser -cminpour le changement ou -aminpour le temps d'accès. Comme d'autres l'ont souligné, je ne pense pas que vous puissiez suivre le temps de création.

kmkaplan
la source
3
vous pouvez supprimer «test» et les backticks. C'est analogue à 'if (test == true)' vs 'if (test)'
pistolets
2
Vous avez raison; Je suppose que je pensais que findretourné non nul quand aucune correspondance n'est trouvée.
canons
4
Vous pouvez supprimer les backticks et faire si test $ (find text.txt -mmin +120)
tommy.carstensen
1
@BroSlow a une meilleure apparence: il n'y a pas «plus d'un» possible. Bien sûr, il text.txtest présumé ne pas être un annuaire.
kmkaplan le
2
Je préfère cette syntaxe:[ "$(find path/to/file -mmin +120)" ] && echo "it is old"
Alfe
42

J'ai toujours aimé l'utiliser date -r /the/file +%spour retrouver son âge.

Vous pouvez également faire touch --date '2015-10-10 9:55' /tmp/filepour obtenir une heure extrêmement fine à une date / heure arbitraire.

nemik
la source
Je cherchais la même chose aujourd'hui. Meilleur!
Umair A.
Merci. J'ai atterri sur cette question SO parce que j'ai cherché sur Google "comment imprimer l'âge du fichier bash". C'est donc exactement ce que je cherchais!
Noah Sussman
5
Merci! avec la seule mise en garde que ce qui précède est un horodatage (pas l'âge) mais peut être utilisé pour calculer l'âge comme tel let AGE=$(($(date +%s)-$(date -r /path/to/file +%s))) [avec l'hypothèse que créé et jamais modifié, ou "âge relatif au mod"]
nhed
function file-age { FILE_CREATED_TIME=`date -r "$1" +%s`; TIME_NOW=`date +%s`; echo "$[ ${TIME_NOW} - ${FILE_CREATED_TIME} ]"; }
turiyag
1
@turiyag Note obligatoire qui $[ ]est, sinon obsolète , au moins ancienne et moins portable , et il faut utiliser à la $(( ))place; et les contre-citations sont plus fragiles que $( ); et les traits d'union dans les noms de fonction peuvent ne pas être entièrement portables. L'essence est bonne, cependant!
michaelb958 - GoFundMonica
23

En utilisant statpour déterminer la date de la dernière modification du fichier, datepour déterminer l'heure actuelle et une utilisation libérale des bashismes, on peut faire le test que vous voulez en fonction de la dernière heure de modification du fichier 1 .

if [ "$(( $(date +"%s") - $(stat -c "%Y" $somefile) ))" -gt "7200" ]; then
   echo "$somefile is older then 2 hours"
fi

Bien que le code soit un peu moins lisible que l' findapproche, je pense que c'est une meilleure approche que de courir findpour regarder un fichier que vous avez déjà "trouvé". De plus, la manipulation des dates est amusante ;-)


  1. Comme Phil l'a correctement noté, l'heure de création n'est pas enregistrée, mais utilisez à la %Zplace de %Yci - dessous pour obtenir "l'heure de changement" qui peut être ce que vous voulez.

[Mettre à jour]

Pour les utilisateurs de Mac, utilisez à la stat -f "%m" $somefileplace de la syntaxe spécifique à Linux ci-dessus

Guss
la source
Dans quel shell la date et la statistique sont-elles intégrées? Mon bash (GNU, 3.2.48) ne les a pas.
Ian Clelland
Oops désolé. statn'est pas intégré - très mauvais de ma part, je vais réparer.
Guss
1
La bonne solution de @Guss est d'installer coretutils avec brew. :-)
Erik Johansson
1
@ErikJohansson Je préfère ne pas exiger l'installation de logiciels supplémentaires lorsque l'utilisation de l'existant fonctionne bien - ce n'est pas Windows, vous savez ;-)
Guss
1
Pour les personnes qui souhaitent l'utiliser mais le modifier, il serait bon de savoir exactement ce qu'il fait: $ (($ (date + "% s") - secondes depuis le 01/01/1970 à 00:00:00 UTC (Epoch) $ (stat -c "% Y" $ somefile))) - Heure de la dernière modification en secondes depuis Epoch -gt "7200" - vérifie si la différence est supérieure à x nombre de secondes.
devo
16

L'heure de création n'est pas enregistrée.

Ce qui est stocké sont trois horodatages (généralement, ils peuvent être désactivés sur certains systèmes de fichiers ou par certaines options du système de fichiers):

  • Heure du dernier accès
  • Heure de la dernière modification
  • Heure du dernier changement

une «modification» du fichier est comptée comme des modifications d'autorisation, un changement de nom, etc. Alors que la modification ne concerne que le contenu.

Philip Reynolds
la source
12

Bien que ctime ne soit pas techniquement le moment de la création, il l'est assez souvent.

Comme ctime il n'est pas affecté par les modifications apportées au contenu du fichier, il n'est généralement mis à jour que lorsque le fichier est créé. Et oui - je vous entends tous crier - il est également mis à jour si vous modifiez les autorisations d'accès ou la propriété ... mais généralement c'est quelque chose qui est fait une fois, généralement au moment où vous placez le fichier là-bas.

Personnellement, j'utilise toujours mtime pour tout, et j'imagine que c'est ce que vous voulez. Mais quoi qu'il en soit ... voici une refonte de la bash "peu attrayante" de Guss, dans une fonction facile à utiliser.

#! / bin / bash
function age () {
   nom de fichier local = 1 $
   local changé = `stat -c% Y" $ filename "`
   local now = `date +% s`
   local écoulé

   laissez écoulé = maintenant changé
   echo $ écoulé
}

fichier = "/"
echo L'âge de $ file est de $ (age "$ file") secondes.
Maryam Jeddian
la source
C'était utile, mais cela n'a pas fonctionné tout de suite pour OSX car stat est implémenté différemment. Le seul moyen compatible entre les systèmes que j'ai trouvé était d'utiliser perl. Le script devrait fonctionner sur Mac si vous remplacez la ligne correspondante par ceci: local changed=$(perl -MFile::stat -e "print stat(\"${filename}\")->mtime") superuser.com/questions/427551/...
Bijou Trouvaille
1
Le «temps de création» est un concept difficile à appréhender. Qu'est-ce que cela signifie pour un fichier copié? Que faire pour un fichier déplacé? Et s'il était déplacé à travers une frontière de périphérique (donc il a été créé à nouveau, dans un sens)? Qu'est-ce que cela signifie pour un fichier compressé puis décompressé? Plusieurs réponses sont possibles ici et aucun consensus n'existe. Mentionner le ctime est bien, cependant, mais je ne le placerais pas sémantiquement près du vague concept de «temps de création». D'autant qu'un simple chmod, appliqué sur le fichier, annulera cette idée. Mais je peux vivre avec toi en faisant ça ;-)
Alfe
@Alfe: Vous manquez le +%sde la seconde mi
Grizly
Cet âge peut être beaucoup plus court: age() { echo $(( $(date +%s) - $(date -r "$1" +%s) )); } (Merci à @Grizly pour la correction!)
Alfe
En fait, il est préférable d'utiliser le temps d'accès qui est une heure de création sur tous les systèmes de fichiers montés avec noatimeoption (ce qui est bon pour les performances, vous devriez donc l'utiliser). Alors utilisez simplement à la %Xplace de %Y.
Nux
7

La recherche est bonne mais je pense que vous pouvez utiliser une autre méthode, surtout si vous avez besoin de combien de secondes est le fichier ancien

date -d "now - $( stat -c "%Y" $filename ) seconds" +%s

en utilisant la date GNU

Voir
la source
use gstat, "brew install coreutils"
Erik Johansson
3

Considérez le résultat de l'outil 'stat':

  File: `infolog.txt'
  Size: 694         Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 11635578    Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/     fdr)   Gid: ( 1000/     fdr)
Access: 2009-01-01 22:04:15.000000000 -0800
Modify: 2009-01-01 22:05:05.000000000 -0800
Change: 2009-01-01 22:05:05.000000000 -0800

Vous pouvez voir ici les trois dates pour l'accès / modifier / changer. Il n'y a pas de date de création. Vous ne pouvez vraiment être sûr que lorsque le contenu du fichier a été modifié (le champ «modifier») ou que son inode a changé (le champ «modifier»).

Exemples de mise à jour des deux champs:

"Modifier" sera mis à jour si quelqu'un a concaténé des informations supplémentaires à la fin du fichier.

"Change" sera mis à jour si quelqu'un a changé les permissions via chmod.

fdr
la source
accordé, stat peut vous donner des informations pertinentes. Mais ce sera assez fastidieux à analyser pour obtenir ce que nous voulons.
PypeBros
0

j'utilise

file_age() {
    local filename=$1
    echo $(( $(date +%s) - $(date -r $filename +%s) ))
}

is_stale() {
    local filename=$1
    local max_minutes=20
    [ $(file_age $filename) -gt $(( $max_minutes*60 )) ]
}

if is_stale /my/file; then
    ...
fi
xpmatteo
la source