Comment puis-je faire un ls puis trier les résultats par date créée?

112

Dans quel ordre les dates sont-elles commandées? Ordre certainement pas alphanumérique.

ls -lttrie par heure de modification. Mais j'ai besoin de temps de création.

InquilineKea
la source
1
Il ne semble y avoir un moyen d'obtenir le temps de création de fichiers sous Linux si le fichier est sur un système de fichiers ext4. Voir: unix.stackexchange.com/a/131347/182996
Kaartic

Réponses:

94

La plupart des ordinateurs n'ont pas de concept de création de fichier. Vous ne pouvez pas faire lsimprimer car les informations ne sont pas enregistrées. Si vous avez besoin d’heure de création, utilisez un système de contrôle de version : définissez l’heure de création comme heure d’enregistrement.

Si votre variante unix a une heure de création, consultez sa documentation. Par exemple, sur Mac OS X (le seul exemple que je connaisse¹), utilisez ls -tU. Windows stocke également une heure de création, mais il n'est pas toujours exposé aux ports des utilitaires Unix, par exemple, Cygwin lsn'a pas l'option de l'afficher. L' statutilitaire peut afficher l'heure de création, appelée "heure de naissance" dans les utilitaires GNU. Ainsi, sous Cygwin, vous pouvez afficher les fichiers triés par heure de naissance avec stat -c '%W %n' * | sort -k1n.

Notez que ctime ( ls -lc) n'est pas l'heure de création du fichier , c'est l' heure de changement d' inode . L'heure de changement d'inode est mise à jour chaque fois que quelque chose concernant le fichier change (contenu ou métadonnées), à l'exception du fait que le temps ctime n'est pas mis à jour lorsque le fichier est simplement lu (même si atime est mis à jour). En particulier, ctime est toujours plus récent que mtime (heure de modification du contenu du fichier), sauf si mtime a été explicitement défini sur une date ultérieure.

Gilles
la source
1
En Cygwin c'est ls -c. ls --helpmontre ce que -cfait quand combiné avec -let -lt.
Aaron D. Marasco
6
@Aaron Non, ctime n'est pas le moment de la création. C'est une confusion commune basée uniquement sur le fait que «ctime» et «création» commencent par la même lettre, mais il n'y a pas de relation entre ctime et l'heure de création. J'ai mis à jour ma réponse pour remédier à cette confusion.
Gilles
LOL ma mauvaise. J'essayais de confirmer la partie Cygwin pour vous (votre IIRC avait une commande possible). Il est spécifiquement indiqué "ctime (heure de la dernière modification des informations sur l'état du fichier)" si j'avais été attentif.
Aaron D. Marasco le
Ajout à @Gilles answer; J'utilise un serveur de fichiers NFS 3.x (incertain sur le système de fichiers sous-jacent; il s'agit d'UFS ou de ZFS, bien que je devine UFS). Sous Redhat 6.x: -Utrie par heure de création. Sous Solaris 10.x: /usr/bin/lsne prend pas en charge -U, /usr/ucb/lsprend en charge -Uet trie par date de création. Ces résultats dépendent évidemment du système de fichiers stockant ces informations en premier lieu.
Brian Vandenberg
1
@ ghoti Si aucun fichier n'a jamais été supprimé (ou déplacé / renommé / lien physique /…) dans le répertoire, l'ordre des répertoires est celui de la création sur certains systèmes de fichiers, mais pas tous. Ce n'est pas vrai sur ext4, par exemple. Je ne sais pas si c'est vrai sur le système de fichiers UFS de Solaris.
Gilles
16

Malheureusement, l’ stat(2)API ne permet pas d’obtenir l’heure de création du fichier, car elle n’est pas exigée par les normes Unix.

Cependant, certains systèmes de fichiers, tels que ext4, enregistrent ces informations dans les métadonnées du fichier. Il n'y a pas de moyen standard pour l'obtenir, mais il y a un moyen ( extuniquement avec les systèmes de fichiers):

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

Vous obtiendrez quelque chose comme ça mentionnant crtime( pas ctime !) Si vous utilisez 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

Le retour de cette commande peut prendre un certain temps, probablement parce qu'il répertorie également toutes les extensions liées au fichier.

Maintenant, si vous voulez commander des fichiers par date de création, je suppose que cela n’est pas facilement (ni correctement) possible. Comme Gilles le dit, ce serait probablement plus facile si vous utilisiez un système de contrôle de révision. Mais vous pouvez essayer de regarder l' ext4API ...

J'ai essayé la stat -c '%w' myfilecommande sur un système de ext4fichiers sur un système Ubuntu (assez récent) sans succès (il ne fait que répondre -).

Totor
la source
Si quelqu'un veut un one-paquebot:f='/path/to/file'; debugfs -R "stat $f" $(df $f|(read a; read a b; echo "$a"))|grep crtime
Boop
3

Voici un script Perl qui utilise la réponse de Totor pour obtenir ce que vous voulez (si votre système de fichiers est ext4).

Fonctionne sur ma machine personnelle (Ubuntu) et mon serveur (CentOS), mais n’a pas été testé au-delà, donc 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
la source
Il convient également de mentionner que certains fichiers peuvent contenir des métadonnées (telles que exif) qui enregistrent la date / heure de création. Si, par exemple, tous vos fichiers sont des photos numériques, vous avez probablement ces données. Voici un exemple utilisant Image :: ExifTool de Perl .
Jonathan Cross
0

Utilisez cette commande ls -lctpour trier les fichiers par date de création.

Rohit Gaikwad
la source
2
yup ce n'est pas la commande "correcte", mais c'est ce que vous recherchez dans la plupart des cas
madnight
Y a-t-il un moyen de faire cela avec "find" pour qu'il imprime tous les fichiers dans les sous-répertoires de cette façon?
Colin D
Le temps ctimeest changé, et pas créer le temps.
Nabi KAZ