Shell-Skript - Alle Dateien nach <Datum> ändern lassen

136

Ich mache das lieber nicht in PHP, also hoffe ich, dass jemand, der sich mit Shell-Skripten auskennt, helfen kann.

Ich benötige ein Skript, das das Verzeichnis rekursiv durchläuft und feststellt, dass alle Dateien mit dem Datum der letzten Änderung größer als ein Datum sind. Anschließend werden die Dateien tariert und komprimiert, wobei die Pfadinformationen beibehalten werden.

Jonathan Leffler
quelle
14
Gute Entscheidung, es nicht in PHP zu tun.
Kredns
1
Sie können jede der anständigen Shell-Skriptsprachen verwenden, z. B. Python, Ruby, Perl, ohne auf PHP zurückzugreifen.
Garrow
3
@garrow Dies wäre in PHP mit einem in einem FilterIterator enthaltenen RecursiveDirctoryIterator ziemlich einfach.
Artefacto

Antworten:

136

so einfach wie:

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

Hier find . -mtime -1werden alle Dateien im (rekursiv) aktuellen Verzeichnis ausgewählt, die am Vortag geändert wurden. Sie können Brüche verwenden, zum Beispiel:

find . -mtime -1.5 | xargs tar --no-recursion -czf myfile.tgz
skrat
quelle
4
Siehe die Antwort von user104848 unten für den Umgang mit Leerzeichen in Ihren Dateinamen
Brian Henk
8
Das Konvertieren eines beliebigen Zeitstempels in einen Bruchteil einer relativen Zeitspanne erscheint weder richtig noch besonders praktisch. Die unten stehende Lösung -newermtist viel besser.
Bobby Jack
5
Beim Versuch, Dateien mit Änderungen in einer Struktur mit Verzeichnissen zu extrahieren, werden die Verzeichnisse selbst als geändert markiert, wodurch der gesamte Ordner archiviert wird. Hinzufügen, -type fum nur Dateien auszuwählen. Dadurch bleibt die Ordnerstruktur erhalten, es werden jedoch nur Dateien mit Änderungen gesichert.
Brent
1
@BrianHenk user104848 änderten ihren Namen, ich bin ziemlich sicher , meinen Sie diese Antwort von (derzeit) Jason Luther obwohl
icc97
4
In der Frage wird gefragt, ob Dateien bis zu einem beliebigen Datum gefunden werden sollen. Mit dieser Antwort können Sie Dateien nach einer beliebigen Anzahl von Tagen in der Vergangenheit finden. Ich denke nicht, dass dies die akzeptierte Antwort sein sollte, ohne einen Schritt hinzuzufügen, um ein Datum in ein Tagesdelta umzuwandeln.
Mark
91

Wenn Sie GNU haben find, gibt es eine Legion relevanter Optionen. Der einzige Nachteil ist, dass die Schnittstelle zu ihnen weniger als hervorragend ist:

  • -mmin n (Änderungszeit in Minuten)
  • -mtime n (Änderungszeit in Tagen)
  • -newer file (Änderungszeit neuer als Änderungszeit der Datei)
  • -daystart (Startzeit von aktueller Zeit bis Tagesbeginn anpassen)
  • Plus Alternativen für die Zugriffszeit und die Zeit zum Ändern oder Erstellen.

Der schwierige Teil besteht darin, die Anzahl der Minuten seit einer bestimmten Zeit zu bestimmen.

Eine erwägenswerte Option: Verwenden Sie diese Option touch, um eine Datei mit dem erforderlichen Änderungszeitstempel zu erstellen. dann findmit verwenden -newer.

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

Dies sucht nach Dateien, die neuer als 2009-01-03T12: 31: 43 sind. In einem Skript /tmp/wotsitwäre dies eindeutig ein Name mit der PID oder einem anderen Wert, um ihn eindeutig zu machen. und es würde eine geben, trapum sicherzustellen, dass es entfernt wird, selbst wenn der Benutzer unterbricht, und so weiter und so fort.

Jonathan Leffler
quelle
65
Stattdessen können Sie -newermt '2009-01-03T12:31:43'vermeiden, dass eine Datei nur als Referenz erstellt werden muss.
Michael Mior
@MichaelMior: Interessant - der 'Find' unter MacOS X 10.7.2 unterstützt -newermt(dokumentiert unter, -newerXYda es mehrere Optionen gibt; X = m, Y = t in diesem Fall). Der GNU-Fund auf den (fast archaischen) Linux-Systemen, die ich verwende, unterstützt die Optionen nicht, daher ist er relativ neu. Danke für die Warnung.
Jonathan Leffler
Diese Option ist in GNU find 4.4.2 enthalten, das ich auf meinem System verwende.
Michael Mior
2
Beachten Sie auch, dass GNU find auch relative Zeiten unterstützt, d. H. -newermt '-2 weeks'.
Cybolic
1
-newermt '2009-01-03T12:31:43'sieht toll aus, aber leider scheint es alles in der falschen Zeitzone zu interpretieren: lists.gnu.org/archive/html/bug-findutils/2012-12/msg00009.html
Antoine
35

Sie können dies direkt mit Teer tun und noch besser:

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

Dadurch wird tar angewiesen, Dateien zu komprimieren, die neuer als der 1. Januar 2014, 18:00:00 Uhr sind.

linux_newbie
quelle
9
Huh ... Ich benutze Unix seit 1984 und habe das nie gewusst. Immer etwas zu lernen.
John
Die Implementierungen davon werden tarnur mit OS X und FreeBSD unterstützt, --newerwas die lange Option für -NGNU ist tar.
Nisetama
Das ist großartig ... Ich konnte es nur mit bzip zum Laufen bringen, ohne -xcvf und eine gz-Erweiterung zu verwenden ... aber ich bin kein Experte.
Phil
17

Dies funktioniert für einige Dateien. Sie möchten "-print0" und "xargs -0" einfügen, falls einer der Pfade Leerzeichen enthält. In diesem Beispiel wird nach Dateien gesucht, die in den letzten 7 Tagen geändert wurden. Verwenden Sie "+7", um diejenigen zu finden, die vor den letzten 7 Tagen geändert wurden.

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

Wie diese Seite warnt, kann xargs dazu führen, dass der Befehl tar bei vielen Argumenten mehrmals ausgeführt wird, und das Flag "-c" kann Probleme verursachen. In diesem Fall möchten Sie Folgendes:

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

Sie können ein komprimiertes Teerarchiv nicht mit tar aktualisieren, daher müssten Sie es in einem zweiten Schritt bzip2 oder gzip.

Jason Luther
quelle
1
In Bezug auf den zweiten Punkt können Sie einen gzip-fähigen Befehl tar wie die Option -z von Gnu tar verwenden, um auch komprimierte Archive zu aktualisieren.
Suncat2000
Oder fügen Sie die Option 'j' hinzu, um bzip in den letzten GNU-Teeren zu verwenden
hd1
3
Wie ich oben in Jonathans Antwort sagte, werden dadurch die Ordner abgerufen, deren Änderungen dazu führen, dass alle ihre Dateien importiert werden. Hinzufügen, -type fum nur Dateien auszuwählen. Dadurch wird die Ordnerstruktur beibehalten, die Dateien werden jedoch nur mit Änderungen gesichert / kürzlich hinzugefügt.
Brent
12

Dies sollte alle Dateien anzeigen, die innerhalb der letzten 7 Tage geändert wurden.

find . -type f -mtime -7 -print

Pfeife das in Teer / Reißverschluss, und du solltest gut sein.

Chris Doggett
quelle
3

Versuchen Sie unter Linux, die Manpage des Befehls find zu lesen

man find

so etwas sollte

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

und du hast es

Luixv
quelle
3

Sie können eine Liste der Dateien erhalten, die zuletzt nach x Tagen geändert wurden mit:

find . -mtime -x

Dann müssen Sie nur noch Dateien in der resultierenden Liste tarieren und komprimieren, z.

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

für alle im letzten Monat geänderten Dateien.

Mouviciel
quelle
3
"-mtime x" stimmt mit Dateien überein, die vor "x" Tagen genau geändert wurden. Verwenden Sie "-mtime -x", um Dateien abzugleichen, die vor weniger als "x" Tagen geändert wurden.
Lance Richardson
3

Ich würde einfach Folgendes tun, um alle neuen Dateien von vor 7 Tagen zu sichern

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

Beachten Sie, dass Sie "vor 7 Tagen" auch durch alles ersetzen können, was Ihren Anforderungen entspricht

Kann sein : date -d'yesterday' +"%d-%b"

Oder auch : date -d'first Sunday last month' +"%d-%b"

Michel
quelle
2

Dieses Skript findet Dateien mit einem Änderungsdatum von zwei Minuten vor und nach dem angegebenen Datum (und Sie können die Werte in den Bedingungen gemäß Ihren Anforderungen ändern).

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

Wenn Sie beispielsweise möchten, dass Dateien nur ein Änderungsdatum vor dem angegebenen Datum haben, können Sie den Parameter in ändern 120, indem Sie die Bedingungen von verwerfen0$DIFF_IN_DATE$DIFF_IN_DATE1 Parameter.

Wenn Sie Dateien mit einem Änderungsdatum 1 Stunde vor und nach dem angegebenen Datum haben möchten, ersetzen Sie sie einfach 120durch 3600in if CONDITION.

Zeeshan Ali
quelle