Wie finde ich Dateien zwischen zwei Daten mit "find"?

21

Ich besitze ein E-Mail-Konto mit über 60 GB E-Mail-Kapazität und habe derzeit große Probleme, E-Mails des letzten Jahres (2011) mit einem E-Mail-Client zu archivieren.

Über das Terminal versuche ich, find zu verwenden, um die Dateien zwischen dem 01.01.2011 und dem 31.12.2011 zu finden, aber ohne Erfolg.

Wie finde ich Dateien zwischen zwei Daten?

Falls relevant, ist das Endziel ein Stapel, der jede gefundene Datei, die dem Datumsintervall entspricht, in einen Ordner verschiebt.

Zuul
quelle
@EliahKagan Zu der Zeit, wenn Speicher dient, waren doppelte Namen kein Problem. Wenn Sie jedoch angeben, dass Sie Zeit haben, sind zusätzliche Informationen zu einem bestimmten Thema immer willkommen :) Außerdem habe ich Ihre Antwort positiv bewertet, da sie zusätzliche Einblicke in dieses Thema bietet.
Zuul
@EliahKagan In diesem Fall ermutige ich Sie, eine Antwort mit der von Ihnen hervorgehobenen praktischen Ausfallsicherheit zu geben :)
Zuul

Antworten:

16

Sie können dieses Skript verwenden:

#!/bin/bash
for i in $(find Your_Mail_Dir/ -newermt "2011-01-01" ! -newermt "2011-12-31"); do
  mv $i /moved_emails_dir/
done
Octávio Filipe Gonçalves
quelle
6
Die Ausgabe von findsollte nicht in einer solchen Shell- forSchleife verarbeitet werden , es sei denn, es wird garantiert, dass keine Datei Leerzeichen im Namen enthält. -exec,, -execdiroder -print0 | xargssollte normalerweise stattdessen verwendet werden; Eine andere mögliche Lösung, die normalerweise weniger wünschenswert ist, jedoch die Verwendung einer forSchleife zulässt , besteht darin, vorübergehend festzulegen, IFSdass ein Leerzeichen nicht als Feldtrennzeichen erkannt wird.
Eliah Kagan
@EliahKagan so was würde der Befehl aussehen dann: Ersetzen Sie einfach findmit exec? Würde es Ihnen etwas ausmachen, eine Antwort hinzuzufügen, die sich mit der Verwendung von Leerzeichen befasst? Sehr geschätzt.
SherylHohman
3
@SherylHohman Nein, benutze den execBefehl nicht. Verwenden Sie einen findBefehl mit der -execauszuführenden Aktion mvoder was auch immer Sie ausführen müssen, wie in der Antwort beschrieben . Wenn find... -execIhren Befehl mit den gefundenen Pfadnamen ausführt, wird keine Shell verwendet, sodass Leerzeichen keine Worttrennung oder Globbing auslösen . (Vielleicht möchten Sie eine neue Frage zu Ihrem speziellen Fall stellen oder genau das fragen, was Sie wissen möchten.)
Eliah Kagan
@EliahKagan Sorry, ich habe deinen Beitrag falsch gelesen - und das war von dir ! Du bist unglaublich! Ihr Beitrag ist ausgezeichnet. Und danke für Ihre Antwort, obwohl es mein eigener Fehler beim Lesen war !!
SherylHohman
40

Bash-Find-Dateien zwischen zwei Daten:

find . -type f -newermt 2010-10-07 ! -newermt 2014-10-08

Gibt eine Liste von Dateien mit Zeitstempeln nach dem 07.10.2010 und vor dem 08.10.2014 zurück

Bash finde Dateien von vor 15 Minuten bis jetzt:

find . -type f -mmin -15

Gibt eine Liste von Dateien mit Zeitstempeln nach 15 Minuten vor, aber vor jetzt zurück.

Bash-Find-Dateien zwischen zwei Zeitstempeln:

find . -type f -newermt "2014-10-08 10:17:00" ! -newermt "2014-10-08 10:53:00"

Gibt Dateien mit Zeitstempeln zwischen 2014-10-08 10:17:00und zurück2014-10-08 10:53:00

Eric Leschinski
quelle
10

Verschieben der Dateien und Aufforderung an den Benutzer, wenn doppelte Namen vorhanden sind:

Wie die Antworten von Subv3rsion und Eric Leschinski zeigen, -newermtwählt das Prädikat Dateien aus, die in jüngerer Zeit als das als Operand angegebene Datum (und die optionale Uhrzeit) geändert wurden. Dateien finden

  • überall in srcdir(dh einschließlich seiner Unterverzeichnisse, deren Unterverzeichnisse usw.)
  • zuletzt geändert (zum Beispiel) im September 2014
  • und verschiebe sie nachdestdir

...Du kannst rennen:

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -i {} destdir/ \;

In einem -execAusdruck übergibt find den Dateinamen, der anstelle von gefunden wurde {}. ;bedeutet, -execdass der auszuführende Befehl und seine Argumente alle angegeben wurden (falls nachfolgende Ausdrücke übergeben werden, um nach -execden Argumenten dieses bestimmten Prädikats zu suchen - siehe unten für ein Beispiel hierfür). ;Es muss maskiert werden, \;damit es von der Shell nicht speziell interpretiert wird. (Ohne \, ;würde den gesamten Ende - findBefehls, das gleiche wie eine neue Zeile zu arbeiten. Auch wenn dieser findBefehl nichts nach dieser hat -execAusdruck, in Ermangelung des passiert ;Argument ist immer noch ein Syntaxfehler.)

Wenn Sie nur die Dateien auflisten möchten - was ratsam ist, wenn Sie nicht sicher sind, wie die alten E-Mails gespeichert sind oder welche anderen Dateien möglicherweise vorhanden sind -, lassen Sie -execalles rechts davon weg. (Bei E-Mails werden häufig E-Mails mit unterschiedlichen Datumsangaben in derselben Datei gespeichert. Bei Personen, die sich in der hier beschriebenen Situation befinden, empfehle ich, vor dem Verschieben von Dateien zu untersuchen, wie sie gespeichert werden.) Wenn Sie ihre Namen drucken und verschieben möchten sie, fügen Sie -printvor -exec.

mv -i Eingabeaufforderungen, wenn eine Datei am Ziel überschrieben wird, z. B .:

  • eine Datei mit dem gleichen Namen existiert aus einer vorherigen Sicherung, oder
  • eine Datei mit dem gleichen Namen , aber aus einem anderen Unterverzeichnis srcdirbereits während derselben verschoben findBetriebes oder
  • (am wenigsten wahrscheinlich) eine Datei mit dem gleichen Namen wurde srcdirwährend des gleichen findVorgangs irgendwo in erstellt , nachdem das Original verschoben wurde, aber bald genug, um gefunden zu werden, sobald findein anderes Unterverzeichnis durchlaufen wurde.

Andere Möglichkeiten zum Aufrufen rm:

Sie haben andere Möglichkeiten, um mit Dateien mit doppelten Namen umzugehen.

  • Ohne -i(dh ) wird normalerweise keine Genehmigung angefordert, dies wird jedoch durchgeführt, wenn die Zieldatei schreibgeschützt ist. ( Manchmal kann es sogar gelingen, eine schreibgeschützte Datei zu überschreiben, z. B. wenn der Benutzer, der sie ausführt, Eigentümer der Datei ist.)mv {} destdir/mvmv
  • Wenn Sie nicht einmal diesen Grad an Interaktivität möchten und mvimmer versuchen möchten , Dateien mit identischen Namen zu überschreiben, verwenden Sie mv -f.
  • Wenn Sie dagegen Quelldateien überspringen möchten, wenn bereits eine Zieldatei mit demselben Namen vorhanden ist, verwenden Sie mv -n.
  • mvAkzeptiert die Flags -bund --backup, um automatisch Dateien mit identischen Namen umzubenennen, die bereits am Ziel vorhanden sind. Standardmäßig ~wird hinzugefügt, um den Sicherungsnamen zu erstellen. Wenn am Ziel bereits eine Datei mit dem Namen und eine Datei mit dem Sicherungsnamen vorhanden ist, wird die Sicherungsdatei überschrieben. Diese Standardeinstellung kann durch beim Aufrufen übergebene Optionen mvund durch Umgebungsvariablen überschrieben werden . Sehen Sie man mvfür weitere Details und das folgende Beispiel.

Verschieben der Dateien und Erstellen von Backups bei doppelten Namen:

Um alle Dateien zu verschieben, sichern Sie Dateien mit doppelten Namen mit einem ~Suffix und verwenden Sie nummerierte Suffixe, wenn Dateien bereits vorhanden sind (um ein Überschreiben zu vermeiden):.~n~.~

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv --backup=existing {} destdir/ \;

Wenn Sie Dateien mit doppelten Namen übersprungen haben und wissen möchten, welche:

Wenn Sie verwenden mv -nund wissen möchten, welche Dateien nicht verschoben wurden, weil es eine andere Datei mit demselben Namen gab, ist es wahrscheinlich die beste Möglichkeit, den ursprünglichen findBefehl erneut auszuführen , ohne -execund alles rechts davon. Dadurch werden ihre Namen gedruckt.
Es werden auch die Namen aller übereinstimmenden Dateien gedruckt, die seit der Ausführung des ursprünglichen find .... -exec ...Befehls erstellt wurden. Für diese Anwendung ist jedoch in der Regel keine vorhanden, da nach Dateien mit alten Änderungszeiten gesucht wird. Es ist möglich, einer Datei einen Änderungszeitstempel zuzuweisen, der älter ist als ihr tatsächliches Alter, touchsowie andere Mechanismen, aber dies scheint in diesem Fall ohne Ihr Wissen nicht wahrscheinlich zu sein.

Sofortige Kenntnis, da Dateien aufgrund doppelter Namen übersprungen werden:

mv -nmeldet keinen speziellen Exit-Code und gibt auch keinen speziellen Exit-Code zurück , wenn keine Datei verschoben wird. Wenn Sie also sofort während der Ausführung über übersprungene Dateien informiert werden möchten, müssen findSie einen separaten Schritt dafür ausführen. Ein Weg ist:

find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -n {} destdir/ \; \
    -exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} destdir \; 

Einige wahrscheinlich geringfügige technische Überlegungen: Dies warnt fälschlicherweise, wenn mveine Datei aus einem anderen Grund als dem am Zielort vorhandenen nicht kopiert werden kann, und beendet die Berichterstellung . Das scheint unwahrscheinlich, aber ich bin nicht sicher, ob es unmöglich ist. Möglicherweise leidet es auch unter einer Race-Bedingung : Es würde warnen, wenn überhaupt kein wirklicher Fehler vorliegt, wenn eine neue Datei mit demselben Namen an derselben Stelle in der sehr kurzen Zeit nach dem Verschieben der alten Datei und vor dem Überprüfen auf erstellt wurde sehen Sie, ob es entfernt wurde. (In Anbetracht der Anwendung bezweifle ich, dass eines der Probleme jemals tatsächlich auftreten würde.) Es könnte neu geschrieben werden, um das Ziel vorher zu überprüfenVerschieben der Datei statt nachher: ​​Die Race-Bedingung bezieht sich dann auf neu erstellte Zieldateien anstelle von Quelldateien. Und während von findoder gemeldete Fehler und Warnungen mv(oder [, obwohl es keine geben sollte) in den Standardfehler geschrieben werden , wird unsere ...skipped (exists in...Warnung in die Standardausgabe geschrieben . Normalerweise werden beide auf Ihrem Terminal angezeigt. Dies kann jedoch von Bedeutung sein, wenn Sie Skripte erstellen.

Ich habe diesen Befehl zum leichteren Lesen in zwei Zeilen aufgeteilt. Es kann auf diese Weise ausgeführt werden, oder Sie können die \und die neue Zeile (dh den Zeilenumbruch) entfernen .

Wie funktioniert dieser findBefehl?

findPrädikate können Tests (wie -typeund -newermt) sein, die für ihre Rückgabewerte verwendet werden, oder Aktionen (wie -printund -exec), die häufig für ihre Nebenwirkungen verwendet werden.

Wenn zwischen Ausdrücken kein Operator (wie -afür und , -ofür oder ) angegeben wird, -awird impliziert. findsetzt Kurzschlussauswertung für und und oder ein . (dh ) ist nur dann wahr, wenn die Ausdrücke p und q beide wahr sind, daher muss q nicht ausgewertet werden, wenn p falsch ist. Obwohl wir oft nicht in diesen Begriffen darüber nachdenken, müssen Tests wahr sein, damit nachfolgende Aktionen oder Tests ausgewertet werden können. Angenommen , ein Verzeichnis wird gefunden. Es wird mit false ausgewertet , sodass anschließend alles übersprungen werden kann.p qp -a qfind-type f

Aktionen werden ebenso wie Tests mit wahr oder falsch bewertet. Auf diese Weise wird -execgemeldet , ob der ausgeführte Befehl erfolgreich war (true) oder fehlgeschlagen ist (false). Wir haben diese -execAusdruckskette mit implizitem und verbunden :

-exec mv -n {} destdir/ \; -exec [ -f {} ] \; -exec printf "\`%s' skipped (exists in \`%s')\\n" {} destdir \;

Dadurch wird versucht, die Datei zu verschieben, und wenn ein mvFehler gemeldet wird, wird der Vorgang beendet. Wir möchten nicht vor einer korrekt übersprungenen Datei warnen, wenn ein anderes Problem darin bestand, dass sie nicht verschoben wurde.

Wenn dies jedoch erfolgreich war, wird der [Befehl ausgeführt . Wie find, [unterstützt seine eigene Art von Ausdrücken als Argumente übergeben. [ -f {} ]überprüft , ob der Operand nach -f(durch an sie übergeben findstatt {}) vorhanden ist (und eine reguläre Datei), und gibt entweder true / Erfolg oder falsch / Versagen.
(Der Exit-Status vieler Befehle wird am besten als Zeichen für Erfolg oder Misserfolg interpretiert, aber [der vorhandene Status wird normalerweise am besten als wahr oder falsch interpretiert.)

Wenn [false zurückgegeben wird, ist die Datei verschwunden und wurde verschoben, sodass keine weiteren Schritte erforderlich sind. Aber wenn [false zurückgegeben wird, ist die Datei immer noch da. Dann findwertet den nächsten -execAusdruck, der die Warnmeldung ausgibt.

Weitere Lektüre

Eliah Kagan
quelle
Wenn ich Zeit habe, hoffe ich , bald einen Abschnitt über Leistungsaspekte und -exec ... +mit hinzuzufügen mv -t.
Eliah Kagan