web-dev-qa-db-fra.com

Comment faire un ls puis trier les résultats par date de création?

Dans quel ordre les datés sont-ils commandés par? Certainement pas un ordre alphanumérique.

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

124
InquilineKea

La plupart des unités n'ont pas de notion de temps de création de fichier. Vous ne pouvez pas faire imprimer ls car les informations ne sont pas enregistrées. Si vous avez besoin de temps de création, utilisez un système de contrôle de version : définissez le temps de création comme le temps d'enregistrement.

Si votre variante Unix a un temps 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 ls n'a pas d'option pour l'afficher. L'utilitaire stat peut afficher l'heure de création, appelée "heure de naissance" dans les utilitaires GNU, donc sous Cygwin vous pouvez afficher les fichiers triés par heure de naissance avec stat -c '%W %n' * | sort -k1n.

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

Malheureusement, l'API stat(2) ne fournit pas un moyen d'obtenir l'heure de création du fichier, car elle est non requise par les normes Unix.

Cependant, certains systèmes de fichiers, comme ext4, enregistrez ces informations dans les métadonnées du fichier. Il n'y a tout simplement pas de moyen standard pour l'obtenir, mais il y a un moyen (ext systèmes de fichiers uniquement):

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

Vous obtiendrez quelque chose comme ça mentionnant crtime ( pasctime!) 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

Cette commande peut prendre un certain temps à revenir, probablement parce qu'elle répertorie également toutes les extensions liées au fichier.

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

J'ai essayé le stat -c '%w' myfile commande sur un ext4 système de fichiers sur un système Ubuntu (assez récent) sans succès (il répond simplement -).

17
Totor

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

Fonctionne sur ma machine domestique (Ubuntu) et mon serveur (CentOS), mais pas 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 };
}
4
Denny

Utilisez cette commande ls -lct pour trier les fichiers selon la date de création.

2
Rohit Gaikwad

Sur les systèmes Linux exécutant le noyau 4.11 ou version ultérieure, avec glibc 2.28 ou version ultérieure, et coreutils 8.31 ou version ultérieure , stat peut afficher l'heure de naissance d'un fichier sur les systèmes de fichiers qui le stockent. Sortie similaire à celle de ls -l peut être obtenu avec

stat -c "%A %4h %U %G %10s %.16w %n" *

et sortie triée avec

stat -c "%W %A %4h %U %G %10s %.16w %n" * | sort -k1,1n | cut -d\  -f2-

Cela utilise ces options de formatage :

  • %W: l'heure de naissance, en secondes depuis l'époque Unix
  • %A: le type de fichier et les autorisations, dans ls -l format
  • %4h: le nombre de liens durs vers le fichier, aligné sur quatre caractères
  • %U: le nom de l'utilisateur propriétaire
  • %G: le nom du groupe propriétaire
  • %10s: la taille du fichier, alignée sur dix caractères
  • %.16w: l'heure de naissance, au format lisible par l'homme, tronquée à seize caractères (suffisamment pour afficher l'année, le mois, le jour, l'heure, les minutes et les secondes)
  • %n: le nom du fichier
1
Stephen Kitt

Pour le faire dans Shell. Les ls ne fournissent pas de temps de création mais changent de temps. Seuls les debugfs peuvent afficher l'heure de création si la partition est ext4

disk=$(df -Th . | grep ext4  |awk '{print $1}')
for file in "."/*
do
    inode=$(ls -i $file | awk '{print $1}')
    crtime=$(debugfs -R "stat <$inode>" $disk 2>/dev/null | grep crtime |  awk -F'-- ' '{print $2}' | awk '{print $2,$3,$5,$4}')

    printf "$crtime\t$file\n"
done | sort -k4 | sort -n -k 3 -k 1M -k2 -k4
0
luigi9876