Kommandozeile: Anhand des Zeitstempels / Timestamp die letzten X Dateien woanders hinkopieren / verschieben
Mich hat gestern ein Freund angerufen und um Hilfe gebeten. Er braucht relativ häufig auf der Kommandozeile die Option, die neuesten angelegten Dateien in ein anderes Verzeichnis zu kopieren (mit verschieben geht das auch). Ob es da nicht einen kleinen schmucken Befehl für diese Aufgabe gibt.
Ja, den gibt es auch – zumindest ist das eine Variante. Auf der Shell führen bekanntlich viele Wege nach Rom.
cp `find . -maxdepth 1 -not -type d -print0 | xargs -0 ls -t | head -4` test/
(wobei test ein von mir im selben Verzeichnis angelegtes Unterverzeichnis ist)
An dieser Stelle möchte ich zwei Dinge tun. Erstens erklären, was die Zeile macht und zweitens, wie man an so ein Problem rangeht, um so einen Befehl auf die Beine zu stellen.
Einige werden sicherlich gerade gähnen, weil das zum Standard-Repertoire gehört. Für andere ist es möglicherweise interessant. Und wer noch nie auf der Shell gearbeitet hat, für den sind die Schritte im Gehirn vielleicht ganz praktisch.
Die Zeile besteht genau genommen aus vier Befehlen (fünf, wenn man xargs dazu zählt).
find . -maxdepth 1 -not -type d -print0
Zunächst einmal möchte ich nur Daten vom Typ Datei und nicht Verzeichnis haben. Das kann ich mithilfe von find
realisieren. find . -maxdepth 1 -not -type d -print0
macht folgendes:
- finde alles in . (das Verzeichnis in dem ich mich befinde) …
- mit einer Tiefe von 1 (maxdepth 1) – also nur das Verzeichnis und keine Unterverzeichnisse
- das keinem Typ d (Verzeichnis) entspricht.
- -print 0 ist für die Übergabe an xargs
- Oder anders gesagt: Liste mir alle Dateien und nur die Dateien des Verzeichnisses ohne Unterverzeichnisse auf.
Somit haben wir nun eine Liste mit allen Dateien, die wir nun nach dem Zeitstempel sortieren.
xargs -0 ls -t
über xargs -0
lesen wir ein, was uns von find
übergeben wurde. Mittels ls -t
sortieren wir das nach dem Zeitstempel der Dateien.
head -4
Mittels head
kann ich mir eine bestimmte Teilmenge herausziehen. In diesem Fall würde head -4
ganz einfach die vier ersten Treffer ausgeben.
An dieser Stelle haben wir das Innere des cp
-Befehls abgehandelt:
find . -maxdepth 1 -not -type d -print0 | xargs -0 ls -t | head -4
Das kannst Du auch einfach so in der Kommandozeile ausführen und es sollte die vier neuesten Dateien wiedergeben.
cp `…` <Verzeichnis>
Nun packen wir den obigen Befehl in eine Kopier-Anweisung und das Ergebnis ist bereits bekannt:
cp `find . -maxdepth 1 -not -type d -print0 | xargs -0 ls -t | head -4` test/
– kopiere die vier neuesten Dateien in das Verzeichnis test
Warum so ausführlich und in dieser Reihenfolge?
Mir fällt immer wieder auf, dass Menschen an solche Probleme mit der Denkweise “ich muss kopieren etwas” und nicht “ich muss etwas kopieren” herangehen. In diesem Fall kümmern wir uns zunächst um das Etwas. Wir Liste grob auf und schließen aus (find
). Dann sortieren wir das Etwas (ls -t
) und geben ein Limit an (head
). Ist das Etwas dann zu unserer Zufriedenheit – dann können wir uns um das Kopieren (cp) kümmern.
Das Ganze funktioniert natürlich auch mit verschieben. Dazu würdest Du cp
durch mv
ersetzen.
Wie gesagt, den Commandline-Ninjas wird das nur ein müdes Lächeln auf die Lippen zaubern. Aber wer sich nicht so häufig mit der Kommandozeile beschäftigt, dem bringt das hoffentlich etwas.