Der beste Weg, um 100 erste Dateien in einem Verzeichnis nach der Zeit sortiert aufzulisten

12

Was wäre der beste Weg, um 100 erste Dateien in einem Verzeichnis aufzulisten, sortiert nach dem erstellten Zeitstempel (älteste zuerst). Das Verzeichnis ist ziemlich groß (ca. 100000 Dateien).

Es dauert schrecklich lange, bis die Leitung zum Kopf geführt ist .

Bearbeiten:

  • Dateisystem ist ext3.
  • Das Begrenzen der Anzahl der Dateien im Ordner ist nicht die Mühe wert, da dies eine seltene Bereinigungsoperation sein wird und die Dateien von einer Software eines Drittanbieters generiert werden.
  • Datei mit modifizierter Zeit anstelle der Erstellungszeit liefert und akzeptable Lösung.


quelle
1
Wenn es sich um eine Bereinigungsoperation handelt, möchten Sie möglicherweise nur find -mtime +<number of days> -deletealle Dateien bereinigen, die älter als ein bestimmtes Alter sind. Das bedeutet, dass keine Sortierung erforderlich ist.
Mikel

Antworten:

14

Sie sagen , dass „ ls zu verrohrt Kopf nimmt eine schreckliche lange Zeit , um einen vollständigen“.

Die Ursache dafür ist nicht ls, sondern die Anzahl der Dateien in Ihrem Verzeichnis. Wenn Sie 100.000 Dateien in einem einzigen Verzeichnis haben, müsste jede Möglichkeit, dieses Problem zu lösen, Informationen zu allen 100.000 Dateien abrufen, bevor überhaupt darüber nachgedacht werden kann, sie zu sortieren oder eine Ausgabe zu drucken.

Wenn es zu lange dauert, besteht die eigentliche Lösung darin, die Dateien auf mehrere Verzeichnisse aufzuteilen.

Können Sie die Anzahl der zu berücksichtigenden Dateien eingrenzen, wenn Sie die Dateien nicht auf mehrere Verzeichnisse verteilen können ? Wenn die Dateinamen beispielsweise ein Datum enthalten, können Sie möglicherweise einen Platzhalter verwenden, damit das System nicht 100.000 Dateien sortieren muss. Oder vielleicht sind sie fortlaufend nummeriert? (Dies kann helfen oder auch nicht, ist aber einen Versuch wert.)

Wie oft versuchst du das zu tun? Vielleicht lohnt es sich, die Ausgabe für die Wiederverwendung zu speichern / zwischenzuspeichern .


Nun eine Frage.

Sind Sie sicher, dass Sie "Erstellungszeit" und nicht "Änderungszeit" meinen ? ? Die meisten Tools können nur "Änderungszeit" und nicht "Erstellungszeit" anzeigen.

Das Erhalten von "Erstellungszeit" ist eine sehr neue Sache, die ein ext4-Dateisystem und einige Tools erfordert, die nicht einfach zu installieren sind.


Wenn Sie die Zeit ändern möchten

Änderungszeit (kurz ctime) bezeichnet die Zeit, zu der sich die Attribute der Datei zuletzt geändert haben.

ls -c sortiert nach ctime.

Sie möchten die Ausgabe in aufsteigender Reihenfolge, nicht in absteigender Reihenfolge, und müssen sie daher mit der -rOption auch umkehren .

Du könntest es also so machen:

ls -cr | head -n 100

Eine längere Lösung für das gleiche Problem mit stat:

find . -mindepth 1 -maxdepth 1 -exec stat -c $'%Z\t%n' '{}' \; |
    sort -k 1n |
    cut -f 2 -d $'\t' |
    head -n 10 |
    sed -e 's/^\.\///'

aber das läuft langsamer als ls -crauf meinem system.


Wenn Sie eine Änderungszeit wünschen

Änderungszeit (kurz mtime) ist der Zeitpunkt, zu dem sich der Inhalt der Datei zuletzt geändert hat.

ls -t sortiert nach mtime.

Ändern Sie ls -crzu ls -tr(beste Option) oder ändern Sie stat -c $'%Z\t%n'zu stat -c $'%Y\t%n'.


Wenn Sie Erstellungszeit benötigen

(crtime für kurz)

Das ist schwieriger.

Stellen Sie zunächst sicher, dass sich das Verzeichnis in einem Dateisystem befindet, das mit formatiert wurde ext4. Sie können verwendentune2fs -l <device name> dies überprüfen.

Dann gibt es ein neues statFormat namens %W, das Ihnen hier weiterhelfen kann. Um es zu bekommen, müssen Sie eine Version von GNU Coreutils herunterladen, die im Oktober 2010 oder danach veröffentlicht wurde, extrahieren, kompilieren und installieren.

Abhängig von Ihrem Kernel könnte dies dann funktionieren (habe es nicht ausprobiert).

find . -mindepth 1 -maxdepth 1 -exec stat -c $'%W\t%n' '{}' \; |
    sort -k 1n |
    cut -f 2 -d $'\t' |
    head -n 10 |
    sed -e 's/^\.\///'

Siehe auch:


Wenn Sie etwa Fehler bekommen "'$\t'

Die '$\t'Notation erfordert bashoder zsh: Es wird in dashoder shauf Ubuntu nicht funktionieren . Wenn Sie wirklich diese Schalen verwenden müssen, müssen Sie eine beliebige Änderungen \tan Ctrl+ V, Tabund entfernen Sie das führende $aus kurz vor der Eröffnung Zitat.

Mikel
quelle
Möglicherweise läuft er nicht mit ext4. Ich starte Ubuntu 10.04 auf allen meinen Rechnern, aber starte JFS auf mehreren Laufwerken. AFAIK JFS unterstützt Erstellungszeitstempel.
Mittwoch,
Tatsächlich. Wir wissen, dass es auf ext3 nicht unterstützt wird und es wird auf ext4 unterstützt. Eine schnelle Suche legt nahe, dass es mit zfs oder FreeBSD-UFS funktionieren könnte, aber keines davon ist unter Ubuntu üblich! Ich bin mir nicht sicher über JFS oder XFS oder irgendetwas anderes. Würde mich über weitere Infos / Links freuen.
Mikel
Vielen Dank für diese sehr umfassende Antwort und für die subtile Erinnerung, spezifischere Fragen zu schreiben;) "Find" erwies sich als ein Gewinner in Bezug auf die Leistung, fs-Typ erwies sich als ext3.
2

Ein anderer Weg, Dinge heute zu tun, könnte für Ihre Leistungsprobleme relevant sein:

I=0; ls -cr /dir/ | while read file; do I=`expr $I + 1`; echo "$file"; if [ $I == 100 ]; then break; fi; done

Das sollte theoretisch viel schneller ausgeben, aber ich denke, es hängt davon ab, woher die Verzögerung kommt. Das lsSortieren der Dateien kann sehr lange dauern.

Oli
quelle
Das bezweifle ich. headwird tatsächlich beendet, sobald genügend Eingaben gelesen wurden. Versuchen Sie, beide mit timevorne zu fahren. Die headVersion ist auf meinem System sowieso viel schneller.
Mikel