come faccio a controllare in bash se un file è stato creato più di x volte fa?


106

Voglio controllare in linux bash se un file è stato creato più di x volte fa.

diciamo che il file si chiama text.txt e il tempo è di 2 ore.

 if [ what? ]
 then
     echo "old enough"
 fi

Risposte:


138

Solo per l'ora di modifica

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

È possibile utilizzare -cminper la modifica o -aminper il tempo di accesso. Come altri hanno sottolineato, non credo che tu possa tenere traccia del tempo di creazione.


3
puoi eliminare "test" e i backtick. Questo è analogo a 'if (test == true)' vs 'if (test)'
pistole

2
Hai ragione; Suppongo che stavo pensando che findrestituisse un valore diverso da zero quando non vengono trovate corrispondenze.
pistole

4
Puoi rilasciare i backtick e fare if test $ (trova text.txt -mmin +120)
tommy.carstensen

1
@BroSlow ha un aspetto migliore: non è possibile "più di uno". Ovviamente text.txtsi presume che non sia una directory.
kmkaplan

2
Preferisco questa sintassi:[ "$(find path/to/file -mmin +120)" ] && echo "it is old"
Alfe

42

Mi è sempre piaciuto usare date -r /the/file +%sper trovare la sua età.

Puoi anche farlo touch --date '2015-10-10 9:55' /tmp/fileper ottenere un tempo estremamente preciso su una data / ora arbitraria.


Oggi stavo cercando la stessa cosa. Migliore!
Umair A.

Grazie. Sono arrivato a questa domanda SO perché ho cercato su Google "come stampare l'età del file bash". Quindi questo è esattamente quello che stavo cercando!
Noah Sussman,

5
Grazie! con l'unico avvertimento che quanto sopra è un timestamp (non l'età) ma può essere utilizzato per calcolare l'età in questo modo let AGE=$(($(date +%s)-$(date -r /path/to/file +%s))) [con l'ipotesi che abbia creato e mai modificato, o "età relativa a 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 Nota obbligatoria che $[ ]è, se non deprecata , almeno vecchia e meno portabile , e si dovrebbe $(( ))invece usare ; e le citazioni arretrate sono più fragili di $( ); e anche i trattini nei nomi delle funzioni potrebbero non essere completamente portabili. L'essenza è buona, però!
michaelb958 - GoFundMonica

23

Usando il statper capire la data dell'ultima modifica del file, dateper capire l'ora corrente e un uso liberale dei bashismi, si può fare il test che si desidera in base all'ora dell'ultima modifica del file 1 .

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

Anche se il codice è un po 'meno leggibile findrispetto all'approccio, penso che sia un approccio migliore rispetto a correre finda guardare un file che hai già "trovato". Inoltre, la manipolazione della data è divertente ;-)


  1. Come ha correttamente notato Phil, l'ora di creazione non viene registrata, ma usa %Zinvece di %Ysotto per ottenere "l'ora di modifica" che potrebbe essere quella che desideri.

[Aggiornare]

Per gli utenti Mac, utilizzare al stat -f "%m" $somefileposto della sintassi specifica per Linux sopra


In quale shell sono incorporate date e statistiche? Il mio bash (GNU, 3.2.48) non li ha.
Ian Clelland,

Oops scusa. statnon è incorporato - molto male da parte mia, lo aggiusterò.
Guss

1
La soluzione giusta di @Guss è installare coretutils con brew. :-)
Erik Johansson

1
@ErikJohansson Preferisco non richiedere l'installazione di software aggiuntivo quando si utilizza quello esistente funziona bene - questo non è Windows, lo sai ;-)
Guss

1
Per le persone che vogliono usarlo ma modificarlo, sarebbe bene sapere esattamente cosa sta facendo: $ (($ (date + "% s") - secondi da 1970-01-01 00:00:00 UTC (Epoch) $ (stat -c "% Y" $ somefile))) - Ora dell'ultima modifica in secondi dall'Epoch -gt "7200" - controlla se la differenza è maggiore di x numero di secondi.
devo il

16

L'ora di creazione non viene memorizzata.

Ciò che viene memorizzato sono tre timestamp (generalmente, possono essere disattivati ​​su determinati file system o da determinate opzioni di file system):

  • Ora dell'ultimo accesso
  • Ora ultima modifica
  • Ultimo cambio orario

una "modifica" al file viene conteggiata come modifiche ai permessi, rinomina ecc. Mentre la modifica riguarda solo il contenuto.


12

Sebbene il ctime non sia tecnicamente il momento della creazione, abbastanza spesso lo è.

Poiché ctime non è influenzato dalle modifiche al contenuto del file, di solito viene aggiornato solo quando il file viene creato. E sì - posso sentirvi tutti urlare - viene aggiornato anche se modifichi i permessi di accesso o la proprietà ... ma generalmente è qualcosa che viene fatto una volta, di solito nello stesso momento in cui metti il ​​file lì.

Personalmente uso sempre mtime per tutto, e immagino che sia quello che vuoi. Ma comunque ... ecco un rimaneggiamento della "poco attraente" bash di Guss, in una funzione facile da usare.

#! / Bin / bash
function age () {
   nome file locale = $ 1
   locale modificato = `stat -c% Y" $ nomefile "`
   local now = `date +% s`
   locale trascorso

   lasciare trascorso = ora cambiato
   echo $ trascorso
}

file = "/"
echo L'età di $ file è $ (età "$ file") secondi.

Questo è stato utile, ma non ha funzionato subito per OSX perché stat è implementato in modo diverso su di esso. L'unico modo compatibile con il sistema incrociato che ho trovato è stato usare perl. Lo script dovrebbe funzionare su Mac se sostituisci la riga corrispondente con questa: local changed=$(perl -MFile::stat -e "print stat(\"${filename}\")->mtime") superuser.com/questions/427551/…
Bijou Trouvaille

1
"Il tempo della creazione" è un concetto difficile da afferrare. Cosa significa per un file copiato? Cosa succede per un file spostato? E se fosse stato spostato oltre il bordo del dispositivo (quindi è stato creato di nuovo, in un certo senso)? Cosa significa per un file compresso e successivamente decompresso? Qui sono possibili diverse risposte e non esiste consenso. Citare il ctime è carino, però, ma non lo metterei semanticamente vicino al vago concetto di "tempo della creazione". Soprattutto perché un semplice chmod, applicato sul file, annullerà quell'idea. Ma posso vivere con te facendo questo ;-)
Alfe

@Alfe: ti manca il +%ssecondo tempo
Grizly

age() { echo $(( $(date +%s) - $(date -r "$1" +%s) )); } Quell'età può essere molto più breve: (Grazie a @Grizly per la correzione!)
Alfe

In realtà è meglio usare il tempo di accesso che è un tempo di creazione su tutti i file system montati con l' noatimeopzione (che è buono per le prestazioni, quindi dovresti usarlo). Quindi usa %Xinvece di %Y.
Nux

7

Il find è buono ma penso che tu possa usare un altro modo, soprattutto se hai bisogno di quanti secondi ha il file vecchio

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

utilizzando la data GNU


usa gstat, "brew install coreutils"
Erik Johansson

3

Considera il risultato dello strumento "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

Puoi vedere qui le tre date per Accesso / modifica / cambio. Non esiste una data di creazione. Puoi essere veramente sicuro solo quando il contenuto del file è stato modificato (il campo "modifica") o il suo inode cambiato (il campo "modifica").

Esempi di quando entrambi i campi vengono aggiornati:

"Modifica" verrà aggiornato se qualcuno ha concatenato informazioni aggiuntive alla fine del file.

"Modifica" verrà aggiornato se qualcuno ha cambiato i permessi tramite chmod.


concesso, stat può fornirti informazioni rilevanti. Ma sarà piuttosto noioso analizzare per ottenere ciò che vogliamo.
PypeBros

0

Io uso

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.