Как мне сделать ls, а затем отсортировать результаты по дате создания?

112

В каком порядке упорядочены датированные? Конечно, не буквенно-цифровой порядок.

ls -ltсортирует по времени модификации. Но мне нужно время создания.

InquilineKea
источник
1
Там же , как представляется, способ получения времени создания файла в Linux , если файл находится на ext4 файловой системы. См .: unix.stackexchange.com/a/131347/182996
kaartic

Ответы:

94

В большинстве офисов нет концепции времени создания файла. Вы не можете lsраспечатать его, потому что информация не записана. Если вам нужно время создания, используйте систему контроля версий : определите время создания как время регистрации.

Если у вашего варианта Unix есть время создания, посмотрите его документацию. Например, в Mac OS X (единственный известный мне пример), используйте ls -tU. Windows также хранит время создания, но не всегда подвержено воздействию портов утилит unix, например, Cygwin lsне имеет возможности показать это. statУтилита может показать время создания, называемое «время рождения» в GNU утилиты, так что под Cygwin вы можете показать файлы , отсортированные по времени рождения с stat -c '%W %n' * | sort -k1n.

Обратите внимание, что ctime ( ls -lc) - это не время создания файла , а время изменения инода . Время изменения inode обновляется всякий раз, когда изменяется что-либо в файле (содержимое или метаданные), за исключением того, что ctime не обновляется, когда файл просто читается (даже если atime обновляется). В частности, ctime всегда более свежее, чем mtime (время изменения содержимого файла), если только mtime не было явно установлено на дату в будущем.

жилль
источник
1
В Cygwin это так ls -c. ls --helpпоказывает, что -cделает в сочетании с -lи -lt.
Аарон Д. Мараско
6
@ Аарон Нет, ctime не время создания. Это распространенная путаница, основанная исключительно на том факте, что «ctime» и «creation» начинаются с одной и той же буквы, но между ctime и временем создания нет никакой связи. Я обновил свой ответ, чтобы устранить эту путаницу.
Жиль
LOL мой плохой. Я пытался подтвердить часть Cygwin для вас (IIRC ваш оригинальный пост имел возможную команду). Это определенно говорит "ctime (время последней модификации информации о статусе файла)", если бы я обратил внимание.
Аарон Д. Мараско
Добавление к ответу @Gilles; Я использую файловый сервер NFS 3.x (не уверен в базовой файловой системе; это либо UFS, либо ZFS, хотя я предполагаю UFS). Под Redhat 6.x: -Uсортировка по времени создания. Под Solaris 10.x: /usr/bin/lsне поддерживает -U, /usr/ucb/lsподдерживает -Uи сортирует по времени создания. Эти результаты, очевидно, зависят от файловой системы, хранящей эту информацию в первую очередь.
Брайан Ванденберг
1
@ghoti Если в каталоге не было ни одного файла, который был удален (или перемещен / переименован / жестко связан /…), то порядок каталогов - порядок создания в некоторых файловых системах, но не во всех. Например, это не так на ext4. Я не знаю, правда ли это в UFS в Solaris.
Жиль
16

К сожалению, stat(2)API не обеспечивает способ получения времени создания файла, так как это не требуется стандартами Unix.

Однако некоторые файловые системы ext4сохраняют эту информацию в метаданных файла. Просто не существует стандартного способа получить его, но есть способ ( extтолько для файловых систем):

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

Вы бы получили что-то подобное упоминание crtime( не ctime !), Если вы используете 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

Эта команда может занять некоторое время, вероятно, потому что она также перечисляет все экстенты, связанные с файлом.

Теперь, если вы хотите упорядочить файлы по дате создания, я думаю, это не легко (и не правильно) возможно. Как говорит Жиль , было бы проще, если бы вы использовали систему контроля версий. Но вы можете попытаться взглянуть на ext4API ...

Я попытался выполнить stat -c '%w' myfileкоманду на ext4файловой системе в (достаточно недавней) системе Ubuntu, но безуспешно (она просто отвечает -).

Totor
источник
Если кто-то хочет один вкладыш:f='/path/to/file'; debugfs -R "stat $f" $(df $f|(read a; read a b; echo "$a"))|grep crtime
Boop
3

Вот скрипт Perl, который использует ответ Totor для достижения того, чего вы хотите (если у вас файловая система ext4).

Работает на моей домашней машине (Ubuntu) и на моем сервере (CentOS), но не тестируется сверх того, поэтому 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
источник
Также стоит упомянуть, что некоторые файлы могут иметь метаданные (например, exif), которые записывают дату / время создания. Если все ваши файлы, например, представляют собой цифровые фотографии, скорее всего, у вас есть эти данные. Вот пример использования Perl Image :: ExifTool .
Джонатан Кросс
0

Используйте эту команду ls -lctдля сортировки файлов по дате создания.

Рохит Гайквад
источник
2
да, это не "правильная" команда, но это то, что вы ищете в большинстве случаев
безумная ночь
Есть ли способ сделать это с «найти», чтобы он печатал все файлы в подкаталогах таким образом?
Колин Д.
Это ctimeвремя изменения, а не время создания.
Наби КАЗ