Como faço um ls e depois classifico os resultados pela data de criação?

112

Em que ordem os datados são ordenados? Certamente não ordem alfanumérica.

ls -ltclassifica por tempo de modificação. Mas eu preciso de tempo de criação.

InquilineKea
fonte
1
não parece ser uma maneira de obter o tempo de criação de arquivos no Linux, se o arquivo estiver em um sistema de arquivos ext4. Veja: unix.stackexchange.com/a/131347/182996
kaartic

Respostas:

94

A maioria dos unices não tem um conceito de hora de criação de arquivo. Você não pode lsimprimi-lo porque as informações não estão gravadas. Se você precisar da hora da criação, use um sistema de controle de versão : defina a hora da criação como a hora do check-in.

Se sua variante unix tiver um tempo de criação, consulte a documentação. Por exemplo, no Mac OS X (o único exemplo que eu conheço), use ls -tU. O Windows também armazena um horário de criação, mas nem sempre é exposto a portas de utilitários unix, por exemplo, o Cygwin lsnão tem uma opção para mostrá-lo. O statutilitário pode mostrar a hora da criação, chamada “hora do nascimento” nos utilitários GNU; portanto, no Cygwin, você pode mostrar os arquivos classificados pela hora do nascimento stat -c '%W %n' * | sort -k1n.

Observe que ctime ( ls -lc) não é o horário de criação do arquivo , é o horário de mudança do inode . O tempo de alteração do inode é atualizado sempre que algo sobre o arquivo é alterado (conteúdo ou metadados), exceto que o ctime não é atualizado quando o arquivo é meramente lido (mesmo que o atime seja atualizado). Em particular, o ctime é sempre mais recente que o mtime (hora da modificação do conteúdo do arquivo), a menos que o mtime tenha sido explicitamente definido como uma data no futuro.

Gilles
fonte
1
Em Cygwin é ls -c. ls --helpmostra o que -cfaz quando combinado com -le -lt.
Aaron D. Marasco 12/12
6
@ Aaron Não, o ctime não é o momento da criação. É uma confusão comum baseada puramente no fato de que "ctime" e "criação" começam com a mesma letra, mas não há relação entre ctime e tempo de criação. Atualizei minha resposta para resolver essa confusão.
Gilles
LOL meu mal. Eu estava tentando confirmar a parte do Cygwin para você (IIRC, sua postagem original tinha um possível comando). Diz especificamente "ctime (hora da última modificação das informações de status do arquivo)" se eu tivesse prestado atenção.
Aaron D. Marasco
Adicionando à resposta do @Gilles; Eu uso um servidor de arquivos NFS 3.x (inseguro no sistema de arquivos subjacente; é UFS ou ZFS, embora eu esteja supondo que UFS). No Redhat 6.x: -Uclassifica por hora de criação. No Solaris 10.x: /usr/bin/lsnão suporta -U, /usr/ucb/lssuporta -Ue classifica por hora de criação. Esses resultados obviamente dependem do sistema de arquivos que armazena essas informações em primeiro lugar.
Brian Vandenberg
1
@ghoti Se nenhum arquivo foi excluído (ou movido / renomeado / hardlinked /…) no diretório, a ordem dos diretórios é a ordem de criação em alguns sistemas de arquivos, mas não em todos. Isso não é verdade no ext4, por exemplo. Não sei se é verdade no UFS do Solaris.
Gilles
16

Infelizmente, a stat(2)API não fornece uma maneira de obter o tempo de criação do arquivo, pois não é exigida pelos padrões Unix.

No entanto, alguns sistemas de arquivos, como ext4, salvam essas informações nos metadados do arquivo. Não existe apenas uma maneira padrão de obtê-lo, mas existe uma maneira ( extapenas sistemas de arquivos):

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

Você obteria algo assim mencionando crtime( não ctime !) Se você usar 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

Esse comando pode levar algum tempo para retornar, provavelmente porque também lista todas as extensões relacionadas ao arquivo.

Agora, se você deseja solicitar arquivos pela data de criação, acho que isso não é fácil (nem adequadamente) possível. Como Gilles diz, provavelmente seria mais fácil se você usasse um sistema de controle de revisão. Mas você pode tentar dar uma olhada na ext4API ...

Eu tentei o stat -c '%w' myfilecomando em um sistema de ext4arquivos em um sistema Ubuntu (recente o suficiente) sem sucesso (ele apenas responde -).

Totor
fonte
Se alguém quiser um forro:f='/path/to/file'; debugfs -R "stat $f" $(df $f|(read a; read a b; echo "$a"))|grep crtime
Boop 27/03
3

Aqui está um script Perl que usa a resposta do Totor para alcançar o que você deseja (se o seu sistema de arquivos for ext4).

Funciona na minha máquina doméstica (Ubuntu) e no meu servidor (CentOS), mas não foi testado além disso, então sim.

#!/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
fonte
Também é bom mencionar que alguns arquivos podem ter metadados (como exif) que registram a data / hora da criação. Se todos os seus arquivos forem fotos digitais, por exemplo, você provavelmente terá esses dados. Aqui está um exemplo usando o Image :: ExifTool do perl .
Jonathan Cruz
0

Use este comando ls -lctpara classificar os arquivos conforme a data de criação.

Rohit Gaikwad
fonte
2
Sim, esse não é o comando "correto", mas é o que você está procurando na maioria dos casos
madnight 16/02/18
existe uma maneira de fazer isso com "find" para que ele imprima todos os arquivos em subdiretórios dessa maneira?
Colin D
O ctimeé tempo de mudança, e não criar tempo.
Nabi KAZ 23/09