Ich suche einen Shell-Einzeiler, um die älteste Datei in einem Verzeichnisbaum zu finden.
72
Dies funktioniert (aktualisiert, um den Vorschlag von Daniel Andersson zu berücksichtigen):
find -type f -printf '%T+ %p\n' | sort | head -n 1
find -type f -printf '%T+ %p\n' | sort | head -1
find
leer ist, weil der Dateiname eine neue Zeile enthält.Dies ist etwas portabler und weil es nicht auf der GNU-
find
Erweiterung basiert-printf
, funktioniert es auch unter BSD / OS X:Der einzige Nachteil hier ist, dass es etwas auf die Größe von beschränkt ist
ARG_MAX
(was für die meisten neueren Kernel irrelevant sein sollte ). Wenn also mehr alsgetconf ARG_MAX
Zeichen zurückgegeben werden (262.144 auf meinem System), erhalten Sie nicht das richtige Ergebnis. Es ist auch nicht POSIX-konform, weil-print0
undxargs -0
nicht.Weitere Lösungen für dieses Problem finden Sie hier: Wie kann ich die neueste (neueste, älteste, älteste) Datei in einem Verzeichnis finden? - Gregs Wiki
quelle
xargs: ls: terminated by signal 13
Fehler als Nebeneffekt ausgegeben. Ich vermute, das ist SIGPIPE. Ich habe keine Ahnung, warum ich keinen ähnlichen Fehler erhalte, wenn ich die Ausgabe von sort in meine Lösung pipe.head
Befehl, der beendet wird, sobald er eine Zeile gelesen hat und somit die Pipe "durchbricht", denke ich. Sie erhalten den Fehler nicht, weil ersort
sich nicht zu beschwerenls
scheint, im anderen Fall jedoch.xargs
diels
mehr als einmal aufgerufen werden müssen. In diesem Fall werden die sortierten Ausgaben dieser mehreren Aufrufe verkettet, wenn sie zusammengeführt werden sollen.ls
es und die älteste Datei, Ihre Lösung Augapfel wahrscheinlich wird die Kommandozeile Längenbegrenzung überrannt, wasls
mehrfach aufgerufen werden. Sie werden die falsche Antwort bekommen, aber Sie werden es nie erfahren.Die folgenden Befehle funktionieren garantiert mit jeder Art von seltsamen Dateinamen:
Die Verwendung eines Nullbytes (
\0
) anstelle eines Zeilenvorschubzeichens (\n
) stellt sicher, dass die Ausgabe von find weiterhin verständlich ist, falls einer der Dateinamen ein Zeilenvorschubzeichen enthält.Der
-z
Schalter bewirkt, dass sowohl sort als auch grep nur Nullbytes als Zeilenendezeichen interpretieren. Da es keinen solchen Schalter für den Kopf gibt, verwenden wirgrep -m 1
stattdessen (nur ein Vorkommen).Die Befehle sind nach Ausführungszeit geordnet (gemessen auf meinem Computer).
Der erste Befehl ist der langsamste, da er die Zeit jeder Datei zuerst in ein für Menschen lesbares Format konvertieren und dann diese Zeichenfolgen sortieren muss. Durch das Weiterleiten an cat wird das Einfärben der Ausgabe vermieden.
Der zweite Befehl ist etwas schneller. Während die Datumskonvertierung noch ausgeführt wird, ist die numerische Sortierung (
sort -n
) der seit der Unix-Epoche verstrichenen Sekunden etwas schneller. sed löscht die Sekunden seit der Unix-Epoche.Der letzte Befehl führt überhaupt keine Konvertierung durch und sollte deutlich schneller sein als die ersten beiden. Der Befehl find selbst zeigt nicht die Uhrzeit der ältesten Datei an, daher ist stat erforderlich.
Verwandte Manpages: find - grep - sed - sort - stat
quelle
Obwohl die akzeptierte Antwort und andere hier die Aufgabe erfüllen, werden bei einem sehr großen Baum alle Dateien sortiert.
Besser wäre es, wenn wir sie einfach auflisten und den Überblick über die ältesten behalten könnten, ohne sie zu sortieren.
Deshalb habe ich mir diese alternative Lösung ausgedacht:
Ich hoffe, es könnte hilfreich sein, auch wenn die Frage ein bisschen alt ist.
Bearbeiten 1: Diese Änderungen ermöglichen das Parsen von Dateien und Verzeichnissen mit Leerzeichen. Es ist schnell genug, um es im Stammverzeichnis auszugeben
/
und die älteste Datei zu finden, die es je gab.Befehl erklärt:
Laufen es:
EDIT 2: Gleiches Konzept, bessere Lösung mit
find
Blick auf die Zugriffszeit (%T
mit der erstenprintf
für Änderungszeit oder stattdessen%C
für Statusänderung ).BEARBEITEN 3: Der folgende Befehl verwendet die Änderungszeit und gibt auch den inkrementellen Fortschritt aus, wenn ältere und ältere Dateien gefunden werden. Dies ist hilfreich, wenn Sie falsche Zeitstempel haben (wie zum Beispiel 1970-01-01):
quelle
ls
ist für Skripte ungeeignet, da die Ausgabe nicht für Computer bestimmt ist. Die Ausgabeformatierung variiert je nach Implementierung. Wie Sie bereits sagten,find
ist es gut für Skripte, aber es kann auch sinnvoll sein, diese Informationen hinzuzufügen, bevor Sie überls
Lösungen sprechen .Bitte benutzen Sie ls - die Manpage zeigt Ihnen, wie Sie das Verzeichnis bestellen können.
Das -n 2 ist so, dass Sie nicht die "Summe" in der Ausgabe erhalten. Wenn Sie nur den Namen der Datei wollen.
Und wenn Sie die Liste in der normalen Reihenfolge benötigen (immer die neueste Datei)
Viel einfacher als die Verwendung von find, viel schneller und robuster - Sie müssen sich keine Gedanken über Dateibenennungsformate machen. Es sollte auch auf fast allen Systemen funktionieren.
quelle
quelle
sort -n
.Es scheint, dass die meisten Leute unter "ältesten" angenommen haben, dass Sie "älteste Änderungszeit" gemeint haben. Das ist wahrscheinlich nach der strengsten Interpretation von "ältesten" korrigiert, aber falls Sie die mit der ältesten Zugriffszeit wollten , würde ich die beste Antwort folgendermaßen modifizieren:
Beachten Sie die
%A+
.quelle
find ./search/dirname -type f -printf '%T+ %h/%f\n'
druckt Datums- und Dateinamen in zwei Spalten.sort | head -n1
behält die Zeile bei, die der ältesten Datei entspricht.echo $2
zeigt die zweite Spalte an, dh den Dateinamen.quelle