it-swarm.com.de

Suchen Sie die neueste Datei nach Änderungsdatum

Wenn ich die neueste Datei (mtime) in einem (großen) Verzeichnis mit Unterverzeichnissen suchen möchte, wie würde ich das tun?

Viele Beiträge, die ich gefunden habe, schlagen eine Variation von ls -lt | head vor (amüsanterweise schlagen viele ls -ltr | tail vor, was dasselbe, aber weniger effizient ist), was in Ordnung ist, es sei denn, Sie haben Unterverzeichnisse (das tue ich).

Andererseits könntest du

find . -type f -exec ls -lt \{\} \+ | head

dies reicht auf jeden Fall für so viele Dateien aus, wie mit einem Befehl angegeben werden können. Wenn Sie also ein großes - Verzeichnis haben, gibt -exec...\+ separate Befehle aus. Daher wird jede Gruppe nach ls in sich selbst sortiert, jedoch nicht über die Gesamtmenge; Der Kopf nimmt daher den letzten Eintrag der ersten Charge auf.

Irgendwelche Antworten?

36
Rich

Sie müssen externe Befehle (als ls) nicht wiederholen, da find über die Aktion -printf alles tun kann, was Sie benötigen:

find /path -printf '%T+ %p\n' | sort -r | head
43
enzotib

Ich hatte heute ein ähnliches Problem, aber ich habe es ohne find angegriffen. Ich brauchte etwas Kurzes, das ich über ssh ausführen konnte, um die zuletzt bearbeitete Datei in meinem Ausgangsverzeichnis zurückzugeben. Das ist ungefähr das, was ich mir ausgedacht habe:

ls -tp | grep -v /$ | head -1

Die Option -p zu ls fügt den Verzeichnissen einen abschließenden Schrägstrich hinzu, die Option grep -v entfernt Zeilen, die mit einem Schrägstrich enden (auch bekannt als alle Verzeichnisse), und die Option head -1 begrenzt die Ausgabe auf eine einzelne Datei.

Dies ist weniger ausführlich als die Verwendung von find, wenn Sie nur den Dateinamen zurückgeben möchten.

8
Pat Regan

Dies ist auf meinem System schneller als printf, obwohl ich nicht verstehe, warum

find /path -type f -exec stat -c "%y %n" {} + | sort -r | head
4
arrange

EDIT: Ich denke, dieser Beitrag ist nicht "nicht besonders nützlich", wie ich dachte, es war. Dies ist eine sehr schnelle Lösung, die nur den Überblick über die zuletzt geänderte Datei behält (anstatt die gesamte Liste der Dateien zu sortieren):

find . -type f -printf '%[email protected] %p\n' | awk 'BEGIN { mostrecenttime = 0; mostrecentline = "nothing"; } { if ($1 > mostrecenttime) { mostrecenttime = $1; mostrecentline = $0; } } END { print mostrecentline; }' | cut -f2- -d ' '

Um die Übersichtlichkeit zu gewährleisten, sollten Sie die Informationen wie folgt auf mehrere Zeilen verteilen:

find . -type f -printf '%[email protected] %p\n' | awk '
    BEGIN { mostrecenttime = 0; mostrecentline = "nothing"; }
    {
        if ($1 > mostrecenttime)
            { mostrecenttime = $1; mostrecentline = $0; }
    }
    END { print mostrecentline; }' | cut -f2- -d ' '

Ende der Bearbeitung


Kein besonders nützlicher Beitrag, aber da bei 'Anordnen' die Geschwindigkeit diskutiert wurde, dachte ich, ich würde dies teilen.

bei den Lösungen von arrang und enzotib werden alle Dateien im Verzeichnis mit ihren mtimes aufgelistet und anschließend sortiert. Wie Sie wissen, ist das Sortieren nicht erforderlich, um das Maximum zu finden. Das Finden des Maximums kann in linearer Zeit erfolgen, aber das Sortieren nimmt n log (n) Zeit in Anspruch [Ich weiß, der Unterschied ist nicht viel, aber dennoch;)]. Ich kann mir keine saubere Art und Weise vorstellen, dies umzusetzen. [BEARBEITEN: Eine ordentliche (wenn auch schmutzig aussehende) und schnelle Implementierung oben bereitgestellt.]

Nächstbeste Sache - Um die zuletzt bearbeitete Datei in einem Verzeichnis zu finden, suchen Sie rekursiv die zuletzt bearbeitete Datei in jedem Unterverzeichnis der Ebene 1. Lassen Sie diese Datei das Unterverzeichnis darstellen. Sortieren Sie nun die Dateien der Ebene 1 zusammen mit den Vertretern der Unterverzeichnisse der Ebene 1. Wenn die Anzahl der Dateien und Unterverzeichnisse der Ebene 1 in jedem Verzeichnis nahezu konstant ist, sollte dieser Prozess linear mit der Gesamtzahl der Dateien skaliert werden.

Das habe ich mir ausgedacht, um das umzusetzen:

findrecent() { { find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1; }
findrecent .

Ich habe dies ausgeführt und eine Reihe von find: findrecent: No such file or directory Fehlern erhalten. Grund: -exec of find läuft in einer anderen Shell. Ich habe versucht, findrecent in .bashrc, .xsessionrc zu definieren, aber dies hat nicht geholfen. Am Ende habe ich auf Putten zurückgegriffen

#!/bin/bash
{ find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1;

in einem Skript namens findrecent in meinem PATH und führen Sie es dann aus.

Ich lief dies, wartete und wartete ohne Ausgabe. Nur um sicherzugehen, dass ich mich nicht mit Endlosschleifen befasst habe, auf die ich die Datei geändert habe

#!/bin/bash
echo "$1" >&2
{ find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1;

und versuchte es erneut. Es hat funktioniert - hat aber 1 Minute 35 Sekunden in meinem Homefolder gedauert - Arrangements und Enzotibs Lösungen haben 1,69 bzw. 1,95 Sekunden gedauert!

Soviel zur Überlegenheit von O (n) gegenüber O (n log (n))! Verdammt du Funktionsaufruf Overhead! [Oder vielmehr Skriptaufruf Overhead]

Aber dieses Skript lässt sich besser skalieren als die früheren Lösungen, und ich wette, es wird auf der Speicherbank von Google schneller laufen als sie. D

2
S Prasanth

Es ist bei weitem nicht so modern, aber es ist auch möglich, dies mit Midnight Commander zu erreichen: Suche nach *, Panelisierung des Ergebnisses, Sortierung nach Änderungszeit in umgekehrter Reihenfolge.

Offensichtlich ist es etwas langsamer als find - mein Ausgangsverzeichnis mit 922000 Dateien wurde in fast 14 Minuten nach mc sortiert, während find weniger als 5 ausgegeben hat - aber es gibt einige Vorteile:

  • Ich würde wahrscheinlich länger als die 9-Minuten-Differenz damit verbringen, einen richtigen Find-Aufruf zu erfinden :)

  • geringere Wahrscheinlichkeit eines Fehlers (vergessen, -r für Sortierung usw. anzugeben - erneut starten)

  • es ist möglich, mit der Ergebnismenge zu spielen, indem die Sortierreihenfolge usw. geändert wird - ohne die Dateien erneut abzufragen.

  • dateioperationen können nur für einige Dateien aus der Ergebnismenge ausgeführt werden. Nach Größe sortieren, einige große Dateien löschen, die nicht benötigt werden

1
Sergey

Verwenden Sie Perl in Konjunktion mit find:

 find my_directory -type f -printf '%[email protected]\t%p\n' | Perl -ane '@[email protected] if ($F[0]>$m[0]); END{print $m[1];}'

Sie erhalten den Namen der Datei mit der größten Epoche == zuletzt geänderten Datei.

1
MUY Belgium