日期按什么顺序排列?当然不是字母数字顺序。
ls -lt
按修改时间排序。但我需要创作时间。
答案1
大多数unices没有文件创建时间的概念。ls
由于未记录信息,因此无法打印。如果您需要创建时间,请使用版本控制系统:定义创建时间为签到时间。
如果您的 UNIX 变体有创建时间,请查看其文档。例如,关于Mac OS X(我知道的唯一例子),使用ls -tU
. Windows 还存储创建时间,但它并不总是暴露给 unix 实用程序的端口,例如 Cygwinls
没有显示它的选项。该stat
实用程序可以显示创建时间,在 GNU 实用程序中称为“出生时间”,因此在 Cygwin 下,您可以使用stat -c '%W %n' * | sort -k1n
.
注意时间( ls -lc
)不是文件创建时间,这是索引节点改变时间。每当文件发生任何更改(内容或元数据)时,inode 更改时间都会更新,但仅读取文件时 ctime 不会更新(即使 atime 已更新)。特别是,ctime 始终比 mtime(文件内容修改时间)更新,除非 mtime 已明确设置为将来的日期。
答案2
不幸的是,stat(2)
API 没有提供获取文件创建时间的方法,因为它是不需要按照 Unix 标准。
但是,某些文件系统(如ext4
或XFS
)确实将此信息保存在文件元数据中。只是没有标准的方法来获得它,但有一种方法:
注:本回答主要涉及Linux系统。
2021 年更新:新的ls
命令选项
根据斯蒂芬·查泽拉斯,ls
coreutils 8.32(以及 glibc 2.28 和 kernel 4.11)的版本现在能够使用新的statx(2)
系统调用(请参阅本答案的末尾)来提取创建时间元数据。
所以要列出文件已排序根据创建/出生日期/时间,您可以使用:
ls -lt --time=birth
该-t
选项将按选项指示的时间类型排序--time
(I怀疑 birth
如果愿意,可以更改creation
)。
添加-r
以反转排序顺序。
debugfs
对于extN
文件系统
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
此命令可能需要一些时间才能返回,可能是因为它还列出了与文件相关的每个范围。
使用 VCS?
现在如果你想命令文件按创建日期排列,我想这不容易(也不正确)实现。作为吉尔斯说,如果您使用版本控制系统,可能会更容易。但你可以尝试看看ext4
API...
命令stat
(2021 年更新)
我在(最近的)Ubuntu 系统上的文件系统上尝试了该stat -c '%w' myfile
命令,但没有成功(它只是回答)。ext4
-
2021 年更新:根据托马斯·尼曼,如果您至少有 coreutils 8.31、glibc 2.28 和 kernel 4.11,则上述命令适用于 Linux。尽管您可以尝试,但它本身不会对文件进行排序:
stat -c '%w %n' * | sort -n
为了实现这一点。%W
如果您不关心人类可读的日期,请使用。添加-r
选项以sort
反转顺序。
2020 年更新:自 Linux 起内核4.11,一个新的statx(2)
系统调用已被介绍。如果文件系统上有可用的信息,它的 API 可以访问文件创建时间。据我所知,还没有标准/稳定的用户空间实用程序允许我们获取此信息,但它可能会在一段时间内出现。这不是一个标准的 POSIX 接口,而是 Linux 特有的接口,说这man
:
statx() 在内核 4.11 中被添加到 Linux 中; glibc 2.28 中添加了库支持。
statx() 是 Linux 特定的。
答案3
在运行内核 4.11 或更高版本、glibc 2.28 或更高版本的 Linux 系统上,以及coreutils 8.31 或更高版本,stat
可以显示文件在存储该文件的文件系统上的诞生时间。ls -l
可以通过以下方式获得类似于的输出
stat -c "%A %4h %U %G %10s %.16w %n" -- *
和排序输出(假设没有带有换行符的文件名)
stat -c "%.10W %A %4h %U %G %10s %.16w %n" -- * |
sort -k1,1n |
cut -d' ' -f2-
和coreutils 8.32 或更高版本,ls
可以使用出生时间显示和排序,使用 --time=birth
选项:
ls -l --time=birth
上面的调用stat
使用这些格式选项:
%.10W
:出生时间,自 Unix 纪元以来的秒数(带有 10 位小数部分)。%A
:文件类型和权限,ls -l
格式%4h
:文件的硬链接数量,与四个字符对齐%U
: 所属用户的名称%G
: 所属组的名称%10s
:文件大小,对齐到十个字符%.16w
:出生时间,采用人类可读的格式,截断为十六个字符(足以显示年、月、日、小时、分钟和秒)%n
: 文件名
答案4
这是一个 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 };
}