Come posso fare una ls e quindi ordinare i risultati per data di creazione?


112

In che ordine sono ordinate le date? Certamente non un ordine alfanumerico.

ls -ltordina per tempo di modifica. Ma ho bisogno di tempo per la creazione.



1
Ci fa sembra essere un modo per ottenere l'ora di creazione di file in Linux se il file si trova su un file system ext4. Vedi: unix.stackexchange.com/a/131347/182996
kaartic

Risposte:


94

La maggior parte dei computer non ha un concetto di tempo di creazione del file. Non è possibile lsstamparlo perché le informazioni non sono registrate. Se è necessario il tempo di creazione, utilizzare un sistema di controllo versione : definire il tempo di creazione come orario di check-in.

Se la tua variante unix ha un tempo di creazione, guarda la sua documentazione. Ad esempio, su Mac OS X (l'unico esempio che conosco¹), utilizzare ls -tU. Windows memorizza anche un tempo di creazione, ma non è sempre esposto alle porte delle utility unix, ad esempio Cygwin lsnon ha un'opzione per mostrarlo. L' statutilità può mostrare l'ora di creazione, chiamata "ora di nascita" nelle utility GNU, quindi sotto Cygwin puoi mostrare i file ordinati per ora di nascita con stat -c '%W %n' * | sort -k1n.

Nota che ctime ( ls -lc) non è l'ora di creazione del file , è l' ora di cambio dell'inode . Il tempo di cambio dell'inode viene aggiornato ogni volta che cambia qualcosa sul file (contenuto o metadati) tranne che il ctime non viene aggiornato quando il file viene semplicemente letto (anche se l'atime viene aggiornato). In particolare, ctime è sempre più recente di mtime (ora di modifica del contenuto del file) a meno che mtime non sia stato esplicitamente impostato su una data futura.


1
In Cygwin lo è ls -c. ls --helpmostra cosa -cfa quando combinato con -le -lt.
Aaron D. Marasco,

6
@Aaron No, il tempo di creazione non è il momento della creazione. È una confusione comune basata esclusivamente sul fatto che "ctime" e "creazione" iniziano con la stessa lettera, ma non esiste alcuna relazione tra ctime e tempo di creazione. Ho aggiornato la mia risposta per affrontare questa confusione.
Gilles,

LOL mio male. Stavo cercando di confermare la parte Cygwin per te (IIRC il tuo post originale aveva un possibile comando). In particolare dice "ctime (ora dell'ultima modifica delle informazioni sullo stato del file)" se avessi prestato attenzione.
Aaron D. Marasco,

Aggiunta alla risposta @Gilles; Uso un file server NFS 3.x (non sono sicuro sul file system sottostante; è UFS o ZFS, anche se sto indovinando UFS). Sotto Redhat 6.x: -Uordina per ora di creazione. In Solaris 10.x: /usr/bin/lsnon supporta -U, /usr/ucb/lssupporta -Ue ordina in base al momento della creazione. Questi risultati dipendono ovviamente dal file system che memorizza tali informazioni in primo luogo.
Brian Vandenberg,

1
@ghoti Se nessun file è mai stato cancellato (o spostato / rinominato / hardlinked / ...) nella directory, allora l'ordine della directory è l'ordine di creazione su alcuni filesystem, ma non tutti. Questo non è vero su ext4, per esempio. Non so se sia vero su UFS di Solaris.
Gilles,

16

Sfortunatamente, l' stat(2)API non fornisce un modo per ottenere il tempo di creazione del file, poiché non è richiesto dagli standard Unix.

Tuttavia, alcuni filesystem, come ext4, salvano queste informazioni all'interno delle metadate dei file. Non esiste un modo standard per ottenerlo, ma esiste un modo ( extsolo filesystem):

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

Otterresti qualcosa del genere menzionando crtime( non ctime !) Se lo usi 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

Il ritorno di questo comando potrebbe richiedere del tempo, probabilmente perché elenca anche tutte le dimensioni relative al file.

Ora, se si desidera ordinare i file in base alla data di creazione, immagino che ciò non sia facilmente (né correttamente) possibile. Come dice Gilles , probabilmente sarebbe più semplice se tu utilizzassi un sistema di controllo delle revisioni. Ma potresti provare a dare un'occhiata ext4all'API ...

Ho provato il stat -c '%w' myfilecomando su un ext4filesystem su un (abbastanza recente) sistema Ubuntu senza successo (risponde solo -).


Se qualcuno vuole un liner:f='/path/to/file'; debugfs -R "stat $f" $(df $f|(read a; read a b; echo "$a"))|grep crtime
Boop

3

Ecco uno script Perl che utilizza la risposta di Totor per ottenere ciò che desideri (se il tuo filesystem è ext4).

Funziona sulla mia macchina di casa (Ubuntu) e sul mio server (CentOS), ma non testato oltre, quindi 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 };
}

Va anche detto che alcuni file potrebbero avere metadati (come exif) che registrano la data / ora di creazione. Se ad esempio tutti i tuoi file sono foto digitali, molto probabilmente hai questi dati. Ecco un esempio usando Image :: ExifTool di perl .
Jonathan Cross,

0

Utilizzare questo comando ls -lctper ordinare i file secondo la data di creazione.


2
sì, questo non è il comando "corretto", ma è quello che stai cercando nella maggior parte dei casi
Madnight

c'è un modo per farlo con "trova" in modo da stampare tutti i file nelle sottodirectory in questo modo?
Colin D,

È l' ctimeora del cambiamento e non creare il tempo.
Nabi KAZ,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.