Shell Script - Ottieni tutti i file modificati dopo <data>


136

Preferirei non farlo in PHP, quindi spero che qualcuno di discreto nello script di shell possa aiutare.

Ho bisogno di uno script che attraversi ricorsivamente la directory e trovi che tutti i file con la data dell'ultima modifica siano maggiori di qualche data. Quindi, eseguirà il tar e comprimerà i file mantenendo le informazioni sul percorso.


14
Buona decisione di non farlo in PHP.
Kredns,

1
Puoi usare uno qualsiasi dei decenti linguaggi di scripting della shell, ad esempio python, ruby, perl senza ricorrere a php.
Garrow,

3
@garrow Questo sarebbe in realtà abbastanza semplice in PHP usando un RecursiveDirctoryIterator incapsulato in un FilterIterator.
Artefacto,

Risposte:


136

semplice come:

find . -mtime -1 | xargs tar --no-recursion -czf myfile.tgz

dove find . -mtime -1selezionerà tutti i file nella directory (ricorsivamente) corrente modificata il giorno prima. puoi usare le frazioni, ad esempio:

find . -mtime -1.5 | xargs tar --no-recursion -czf myfile.tgz

4
Vedi la risposta di user104848 qui sotto per come gestire gli spazi nei nomi dei tuoi file
Brian Henk,

8
La conversione di un timestamp arbitrario in una quantità di tempo relativa e frazionaria non sembra né corretta né particolarmente conveniente. La soluzione che segue -newermtè molto più bella.
Bobby Jack,

5
Quando si tenta di estrarre qualsiasi file con modifiche in una struttura con directory, le directory stesse vengono contrassegnate come modificate e l'archiviazione dell'intera cartella. Aggiungi -type fper selezionare solo i file. Ciò mantiene la struttura delle cartelle, ma esegue il backup dei file solo con modifiche.
Brent,

1
@BrianHenk user104848 cambiato il loro nome, sono abbastanza sicuro che vuoi dire questa risposta da (attualmente) Jason Luther però
icc97

4
La domanda chiede di trovare i file entro una data arbitraria. Questa risposta è come trovare i file per un numero arbitrario di giorni nel passato. Non penso che questa dovrebbe essere la risposta accettata senza aggiungere un passaggio per convertire una data in un delta del giorno.
Segna il

91

Se hai GNU find, allora ci sono una legione di opzioni pertinenti. L'unico inconveniente è che l'interfaccia per loro è meno che stellare:

  • -mmin n (tempo di modifica in minuti)
  • -mtime n (tempo di modifica in giorni)
  • -newer file (tempo di modifica più recente del tempo di modifica del file)
  • -daystart (regola l'ora di inizio dall'ora corrente all'inizio della giornata)
  • Inoltre alternative per il tempo di accesso e il tempo di "modifica" o "creazione".

La parte difficile è determinare il numero di minuti da tempo.

Un'opzione da considerare: usare touchper creare un file con il timestamp di modifica richiesto; quindi utilizzare findcon -newer.

touch -t 200901031231.43 /tmp/wotsit
find . -newer /tmp/wotsit -print
rm -f /tmp/wotsit

Questo cerca file più recenti di 2009-01-03T12: 31: 43. Chiaramente, in uno script, /tmp/wotsitsarebbe un nome con il PID o altro valore per renderlo unico; e ci sarebbe un trapper assicurarsi che venga rimosso anche se l'utente lo interrompe, e così via e così via.


65
Invece, è possibile utilizzare -newermt '2009-01-03T12:31:43'per evitare la necessità di creare un file solo come riferimento.
Michael Mior,

@MichaelMior: Interessante - la 'trova' su MacOS X 10.7.2 supporta -newermt(documentata sotto -newerXYdato che ci sono più opzioni; X = m, Y = t in questo caso). La ricerca GNU sui sistemi Linux (quasi arcaici) che uso non supporta le opzioni, quindi è un arrivo relativamente recente. Grazie per il testa a testa.
Jonathan Leffler,

Questa opzione è presente in GNU find 4.4.2 che sto usando sul mio sistema.
Michael Mior

2
Si noti inoltre che GNU find supporta anche i tempi relativi, ad es. -newermt '-2 weeks'.
Cybolic

1
-newermt '2009-01-03T12:31:43'sembra fantastico, ma purtroppo sembra interpretare tutto nel fuso orario sbagliato: lists.gnu.org/archive/html/bug-findutils/2012-12/msg00009.html
antoine

35

Puoi farlo direttamente con tar e ancora meglio:

tar -N '2014-02-01 18:00:00' -jcvf archive.tar.bz2 files

Questo indica a tar di comprimere i file più recenti del 1 gennaio 2014, alle 18:00:00.


9
Eh ... uso Unix dal 1984 e non l'ho mai saputo. Sempre qualcosa da imparare.
Giovanni,

Le implementazioni di tarquesto vengono fornite con OS X e FreeBSD supportano solo --newerl'opzione lunga per -NGNU tar.
nisetama,

È fantastico ... Potrei farlo funzionare solo con bzip, non usando -xcvf e un'estensione gz ... ma non sono un esperto.
phil

17

Questo funzionerà per un certo numero di file. Si desidera includere "-print0" e "xargs -0" nel caso in cui uno dei percorsi contenga spazi. Questo esempio cerca i file modificati negli ultimi 7 giorni. Per trovare quelli modificati prima degli ultimi 7 giorni, usa "+7".

find . -mtime -7 -print0 | xargs -0 tar -cjf /foo/archive.tar.bz2

Come questa pagina avverte, xargs può far eseguire il comando tar più volte se ci sono molti argomenti e il flag "-c" potrebbe causare problemi. In tal caso, vorresti questo:

find . -mtime -7 -print0 | xargs -0 tar -rf /foo/archive.tar

Non puoi aggiornare un archivio tar compresso con tar, quindi dovresti bzip2 o gzip in un secondo passaggio.


1
Per quanto riguarda il secondo punto, puoi usare un comando tar abilitato per gzip, come l'opzione -z di Gnu tar, anche per aggiornare gli archivi zippati.
Suncat2000,

Oppure aggiungi l'opzione 'j' per usare bzip nelle recenti tars GNU
hd1

3
Come ho detto sopra sulla risposta di Jonathan, questo prenderà le cartelle che hanno delle modifiche che causano l'importazione di tutti i loro file. Aggiungi -type fper selezionare solo i file. Ciò mantiene la struttura delle cartelle, ma esegue il backup dei file solo con modifiche / aggiunte di recente.
Brent,

12

Questo dovrebbe mostrare tutti i file modificati negli ultimi 7 giorni.

find . -type f -mtime -7 -print

Inseriscilo in tar / zip e dovresti essere bravo.


4

Farei semplicemente quanto segue per eseguire il backup di tutti i nuovi file di 7 giorni fa

tar --newer $(date -d'7 days ago' +"%d-%b") -zcf thisweek.tgz .

nota che puoi anche sostituire "7 giorni fa" con tutto ciò che soddisfa le tue necessità

Può essere : date -d'yesterday' +"%d-%b"

O anche : date -d'first Sunday last month' +"%d-%b"


3

bene sotto Linux prova a leggere la pagina man del comando find

man find

qualcosa del genere dovrebbe

 find . -type f -mtime -7 -print -exec cat {} \; | tar cf - | gzip -9

e ce l'hai


3

Puoi ottenere un elenco di file modificati l'ultima volta dopo x giorni fa con:

find . -mtime -x

Quindi devi solo tarare e comprimere i file nell'elenco risultante, ad esempio:

tar czvf mytarfile.tgz `find . -mtime -30`

per tutti i file modificati nell'ultimo mese.


3
"-mtime x" corrisponde ai file modificati esattamente "x" giorni fa, usa "-mtime -x" per abbinare i file modificati meno di "x" giorni fa.
Lance Richardson,

2

Questo script troverà i file con una data di modifica di due minuti prima e dopo la data specificata (e puoi cambiare i valori nelle condizioni secondo il tuo requisito)

PATH_SRC="/home/celvas/Documents/Imp_Task/"
PATH_DST="/home/celvas/Downloads/zeeshan/"

cd $PATH_SRC
TODAY=$(date  -d "$(date +%F)" +%s)
TODAY_TIME=$(date -d "$(date +%T)" +%s)


for f in `ls`;
do
#       echo "File -> $f"
        MOD_DATE=$(stat -c %y "$f")
        MOD_DATE=${MOD_DATE% *}
#       echo MOD_DATE: $MOD_DATE
        MOD_DATE1=$(date -d "$MOD_DATE" +%s)
#       echo MOD_DATE: $MOD_DATE

DIFF_IN_DATE=$[ $MOD_DATE1 - $TODAY ]
DIFF_IN_DATE1=$[ $MOD_DATE1 - $TODAY_TIME ]
#echo DIFF: $DIFF_IN_DATE
#echo DIFF1: $DIFF_IN_DATE1
if [[ ($DIFF_IN_DATE -ge -120) && ($DIFF_IN_DATE1 -le 120) && (DIFF_IN_DATE1 -ge -120) ]]
then
echo File lies in Next Hour = $f
echo MOD_DATE: $MOD_DATE

#mv $PATH_SRC/$f  $PATH_DST/$f
fi
done

Per esempio si desidera che i file con data di modifica prima della data indicata solo, si può cambiare 120a 0nel $DIFF_IN_DATEparametro scartando le condizioni di$DIFF_IN_DATE1 parametro.

Allo stesso modo, se si desidera che i file abbiano la data di modifica 1 ora prima e dopo la data specificata, è sufficiente sostituirli 120con 3600in if CONDITION.

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.