Wie mache ich ein ls und sortiere dann die Ergebnisse nach Erstellungsdatum?

112

In welcher Reihenfolge sind die Daten sortiert nach? Mit Sicherheit keine alphanumerische Reihenfolge.

ls -ltsortiert nach Änderungszeit. Aber ich brauche Erstellungszeit.

InquilineKea
quelle
1
Es hat offenbar ein Weg , um die Datei Erstellungszeit in Linux zu bekommen , wenn die Datei auf einem ext4 - Dateisystem ist. Siehe: unix.stackexchange.com/a/131347/182996
kaartic

Antworten:

94

Die meisten Unices haben keine Vorstellung von der Dateierstellungszeit. Sie können es nicht lsdrucken, da die Informationen nicht aufgezeichnet werden. Wenn Sie Erstellungszeit benötigen, verwenden Sie ein Versionskontrollsystem : Definieren Sie die Erstellungszeit als Eincheckzeit.

Wenn Ihre Unix-Variante eine Erstellungszeit hat, schauen Sie in die Dokumentation. Verwenden Sie beispielsweise unter Mac OS X (das einzige mir bekannte Beispiel¹) ls -tU. Windows speichert auch eine Erstellungszeit, ist jedoch nicht immer für Ports von Unix-Dienstprogrammen verfügbar, z. B. hat Cygwin lskeine Option, diese anzuzeigen. Das statHilfsprogramm kann die Erstellungszeit anzeigen, die in GNU-Hilfsprogrammen als "Geburtszeit" bezeichnet wird, sodass Sie unter Cygwin Dateien anzeigen können, die nach Geburtszeit sortiert sind stat -c '%W %n' * | sort -k1n.

Beachten Sie, dass ctime ( ls -lc) nicht die Erstellungszeit der Datei ist , sondern die Inode- Änderungszeit. Die Inode-Änderungszeit wird jedes Mal aktualisiert, wenn sich etwas an der Datei ändert (Inhalt oder Metadaten), mit der Ausnahme, dass die ctime nicht aktualisiert wird, wenn die Datei lediglich gelesen wird (auch wenn die atime aktualisiert wird). Insbesondere ist die ctime immer aktueller als die mtime (Änderungszeit des Dateiinhalts), es sei denn, die mtime wurde explizit auf ein Datum in der Zukunft festgelegt.

Gilles
quelle
1
In Cygwin ist es so ls -c. ls --helpzeigt, was -cin Kombination mit -lund funktioniert -lt.
Aaron D. Marasco
6
@Aaron Nein, die Uhrzeit ist nicht die Erstellungszeit. Es ist eine weit verbreitete Verwirrung, die lediglich auf der Tatsache beruht, dass „ctime“ und „creation“ mit demselben Buchstaben beginnen, es jedoch keinen Zusammenhang zwischen ctime und creation time gibt. Ich habe meine Antwort aktualisiert, um diese Verwirrung zu beseitigen.
Gilles
LOL mein schlechtes. Ich habe versucht, den Cygwin-Teil für Sie zu bestätigen (IIRC Ihr ursprünglicher Beitrag hatte einen möglichen Befehl). Es wird ausdrücklich "ctime (Zeitpunkt der letzten Änderung der Dateistatusinformationen)" angezeigt, wenn ich darauf geachtet habe.
Aaron D. Marasco
Hinzufügen zu @ Gilles Antwort; Ich verwende einen NFS 3.x-Dateiserver (auf dem zugrunde liegenden Dateisystem nicht sicher; es ist entweder UFS oder ZFS, obwohl ich UFS vermute). Unter Redhat 6.x: -USortiert nach Erstellungszeit. Unter Solaris 10.x: /usr/bin/lsUnterstützt nicht -U, /usr/ucb/lsunterstützt -Uund sortiert nach Erstellungszeit. Diese Ergebnisse hängen natürlich davon ab, ob das Dateisystem diese Informationen überhaupt speichert.
Brian Vandenberg
1
@ghoti Wenn in dem Verzeichnis keine Dateien gelöscht (oder verschoben / umbenannt / fest verbunden /…) wurden, ist die Verzeichnisreihenfolge bei einigen Dateisystemen die Erstellungsreihenfolge, jedoch nicht bei allen. Dies gilt beispielsweise nicht für ext4. Ich weiß nicht, ob dies für Solaris 'UFS zutrifft.
Gilles
16

Leider bietet die stat(2)API keine Möglichkeit, die Zeit zum Erstellen von Dateien abzurufen, da dies nach den Unix-Standards nicht erforderlich ist .

Einige Dateisysteme ext4speichern diese Informationen jedoch in den Dateimetadaten. Es gibt einfach keinen Standard-Weg, um es zu bekommen, aber es gibt einen Weg ( extnur Dateisysteme):

debugfs -R 'stat partition/relative/path/to/file' /dev/sda1

Sie würden etwas wie das erwähnen crtime( nicht ctime !) Erhalten, wenn Sie verwenden ext4.

 ctime: 0x513a50e5:d4e448f0 -- Fri Mar  8 21:58:13 2013
 atime: 0x513dd8f1:04df0b20 -- Mon Mar 11 14:15:29 2013
 mtime: 0x513a50e5:d4e448f0 -- Fri Mar  8 21:58:13 2013
crtime: 0x513a259a:35191a3c -- Fri Mar  8 18:53:30 2013

Es kann einige Zeit dauern, bis dieser Befehl zurückgegeben wird, wahrscheinlich weil er auch alle Bereiche auflistet, die sich auf die Datei beziehen.

Wenn Sie Dateien nach Erstellungsdatum bestellen möchten, ist dies wahrscheinlich nicht einfach (noch nicht richtig) möglich. Wie Gilles sagt, wäre es wahrscheinlich einfacher, wenn Sie ein Revisionskontrollsystem verwenden würden. Aber Sie können versuchen, einen Blick auf die ext4API zu werfen ...

Ich habe den stat -c '%w' myfileBefehl auf einem ext4Dateisystem auf einem (aktuell genug) Ubuntu-System ohne Erfolg ausprobiert (es antwortet nur -).

Totor
quelle
Wenn jemand einen Einzeiler möchte:f='/path/to/file'; debugfs -R "stat $f" $(df $f|(read a; read a b; echo "$a"))|grep crtime
Boop
3

Hier ist ein Perl-Skript, das die Antwort von Totor verwendet, um das zu erreichen, was Sie wollen (wenn Ihr Dateisystem ext4 ist).

Funktioniert auf meinem Heimcomputer (Ubuntu) und meinem Server (CentOS), aber nicht darüber hinaus getestet, also ymmv.

#!/usr/bin/env perl

use Modern::Perl '2009';

use DateTime;


# Open the current directory for reading
opendir my $dh, "." or die "Unable to open directory: $!";

# Create a hash to save results into
my %results;
my %datestamp;

# Loop through the directory getting creation date stats for each file
while ( my $filename = readdir $dh ) {
    # Skip non-files
    next if $filename eq '.' or $filename eq '..';

    # Save the ls output for this file/directory
    $results{ $filename } = `ls -ld $filename`;

    my $stats = `debugfs -R 'stat $filename' /dev/sda6 2>/dev/null`;
    # crtime: 0x51cd731c:926999ec -- Fri Jun 28 12:27:24 2013
    $stats =~ m/crtime\: \w+\:\w+ -- (.+?)\n/s;
    my $datestring = $1;

    # Dissect date with a regexp, ick
    my %months = (
        'Jan' => '1',
        'Feb' => '2',
        'Mar' => '3',
        'Apr' => '4',
        'May' => '5',
        'Jun' => '6',
        'Jul' => '7',
        'Aug' => '8',
        'Sep' => '9',
        'Oct' => '10',
        'Nov' => '11',
        'Dec' => '12',
    );
    $datestring =~ m/\w+ (\w+)  ?(\d+) (\d\d)\:(\d\d)\:(\d\d) (\d\d\d\d)/;

    # Convert date into a more useful format
    my $dt = DateTime->new(
        year   => $6,
        month  => $months{$1},
        day    => $2,
        hour   => $3,
        minute => $4,
        second => $5,
    );

    # Save the datestamp for this result
    $datestamp{ $filename } = $dt->iso8601;
}

# Output in date order
my @filenames = sort { $datestamp{$a} gt $datestamp{$b} } keys %datestamp;

foreach my $filename ( @filenames ) {
    print $results{ $filename };
}
Denny
quelle
Gut zu erwähnen ist auch, dass einige Dateien Metadaten (z. B. exif) enthalten können, die das Erstellungsdatum und die Erstellungszeit aufzeichnen. Handelt es sich bei all Ihren Dateien beispielsweise um digitale Fotos, verfügen Sie höchstwahrscheinlich über diese Daten. Hier ist ein Beispiel mit Perls Image :: ExifTool .
Jonathan Cross
0

Verwenden Sie diesen Befehl ls -lct, um Dateien nach Erstellungsdatum zu sortieren.

Rohit Gaikwad
quelle
2
yup das ist nicht der "richtige" Befehl, aber es ist das, wonach Sie in den meisten Fällen suchen
madnight
Gibt es eine Möglichkeit, dies mit "find" zu tun, damit alle Dateien in Unterverzeichnissen auf diese Weise gedruckt werden?
Colin D
Dies ctimeist die Änderungszeit und nicht die Erstellungszeit.
Nabi KAZ