Verschieben der Dateien und Aufforderung an den Benutzer, wenn doppelte Namen vorhanden sind:
Wie die Antworten von Subv3rsion und Eric Leschinski zeigen, -newermt
wä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 nach
destdir
...Du kannst rennen:
find srcdir -type f -newermt 2014-08-31 ! -newermt 2014-09-30 -exec mv -i {} destdir/ \;
In einem -exec
Ausdruck übergibt find den Dateinamen, der anstelle von gefunden wurde {}
. ;
bedeutet, -exec
dass der auszuführende Befehl und seine Argumente alle angegeben wurden (falls nachfolgende Ausdrücke übergeben werden, um nach -exec
den 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 - find
Befehls, das gleiche wie eine neue Zeile zu arbeiten. Auch wenn dieser find
Befehl nichts nach dieser hat -exec
Ausdruck, 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 -exec
alles 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 -print
vor -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
srcdir
bereits während derselben verschoben find
Betriebes oder
- (am wenigsten wahrscheinlich) eine Datei mit dem gleichen Namen wurde
srcdir
während des gleichen find
Vorgangs irgendwo in erstellt , nachdem das Original verschoben wurde, aber bald genug, um gefunden zu werden, sobald find
ein 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/
mv
mv
- Wenn Sie nicht einmal diesen Grad an Interaktivität möchten und
mv
immer 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
.
mv
Akzeptiert die Flags -b
und --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 mv
und durch Umgebungsvariablen überschrieben werden . Sehen Sie man mv
fü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 -n
und 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 find
Befehl erneut auszuführen , ohne -exec
und 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, touch
sowie 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 -n
meldet 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 find
Sie 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 mv
eine 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 find
oder 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 find
Befehl?
find
Prädikate können Tests (wie -type
und -newermt
) sein, die für ihre Rückgabewerte verwendet werden, oder Aktionen (wie -print
und -exec
), die häufig für ihre Nebenwirkungen verwendet werden.
Wenn zwischen Ausdrücken kein Operator (wie -a
für und , -o
für oder ) angegeben wird, -a
wird impliziert. find
setzt 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 q
p -a q
find
-type f
Aktionen werden ebenso wie Tests mit wahr oder falsch bewertet. Auf diese Weise wird -exec
gemeldet , ob der ausgeführte Befehl erfolgreich war (true) oder fehlgeschlagen ist (false). Wir haben diese -exec
Ausdruckskette 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 mv
Fehler 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 find
statt {}
) 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 find
wertet den nächsten -exec
Ausdruck, der die Warnmeldung ausgibt.
Weitere Lektüre