不使用 `ls` 按 `ls -l` 日期排序

不使用 `ls` 按 `ls -l` 日期排序

我有一个包含一堆ls -l输出的文本文件,例如:

-rw-r--r-- 1 root root 7554952082 Dec 15 22:11 /var/spool/stuff/Investigation/messages.tgz
-rw-r--r-- 1 root root 4315 Mar  3  2015 /var/spool/stuff/redoneagain.tgz
-rw-r--r-- 1 root root 429786 Apr 22  2014 /var/spool/stuff/random20.tgz

我无法运行新ls命令,因为某些文件不再存在。

我该怎么做才能按照这些可悲的人类可读日期对这些文件进行排序?它们不是按字母顺序排列的,有些甚至不显示年份信息。

编辑以下是包含虚假文件名的更大的样本集:

-rw-r--r-- 1 root root 67746 Feb 23 2015 /fake/file/1
-rw-r--r-- 1 root root 665081504 Nov 10 22:26 /fake/file/2
-rw-r--r-- 1 root root 2268687431 Sep 11 2015 /fake/file/3
-rw-r--r-- 1 root root 2322223712 Sep 14 2015 /fake/file/4
-rw-r--r-- 1 root root 67413 Feb 25 2015 /fake/file/5
-rw-r--r-- 1 root root 193782 Oct 28 2013 /fake/file/6
-rw-r--r-- 1 root root 79802627 Nov 23 23:19 /fake/file/7
-rw-r--r-- 1 root root 53336532 Nov 23 23:20 /fake/file/8
-rw-r--r-- 1 root root 99797 Nov 10 00:27 /fake/file/9
-rw-r--r-- 1 root root 19618 Apr 17 2014 /fake/file/10
-rw-r--r-- 1 root root 1856 Oct 18 2013 /fake/file/11
-rw-r--r-- 1 root root 90213 Sep 23 2015 /fake/file/12
-rw-r--r-- 1 root root 1924 Sep 24 2015 /fake/file/13
-rw-r--r-- 1 root root 563907311 Nov 16 17:37 /fake/file/14
-rw-r--r-- 1 root root 193855 Oct 22 2013 /fake/file/15
-rw-r--r-- 1 root root 7554952082 Dec 15 22:11 /fake/file/16
-rw-r--r-- 1 root root 4315 Mar 3 2015 /fake/file/17
-rw-r--r-- 1 root root 429786 Apr 22 2014 /fake/file/18
-rw-r--r-- 1 root root 4870 Apr 18 2014 /fake/file/19
-rw-r--r-- 1 root root 87392 Feb 3 2015 /fake/file/20
-rw-r--r-- 1 root root 552396373 Dec 21 21:25 /fake/file/21
-rw-r--r-- 1 root root 3959214957 Aug 1 2015 /fake/file/22
-rw-r--r-- 1 root root 4678389972 Jul 31 2015 /fake/file/23
-rw-r--r-- 1 root root 5371125 Aug 27 2015 /fake/file/24
-rw-r--r-- 1 root root 2523669282 Jul 24 2015 /fake/file/25
-rw-r--r-- 1 root root 2138312957 Jul 27 2015 /fake/file/26
-rw-r--r-- 1 root root 87953 Feb 20 2015 /fake/file/27
-rw-r--r-- 1 root root 480600954 Nov 17 17:59 /fake/file/28
-rw-r--r-- 1 root root 1009402595 Oct 21 2014 /fake/file/29
-rw-r--r-- 1 root root 14991 Apr 15 2014 /fake/file/30
-rw-r--r-- 1 root root 5993812 Apr 16 2015 /fake/file/31
-rw-r--r-- 1 root root 4278 Feb 27 2015 /fake/file/32
-rw-r--r-- 1 root root 4141 Oct 18 2013 /fake/file/33
-rw-r--r-- 1 root root 8483609907 Aug 21 2015 /fake/file/34
-rw-r--r-- 1 root root 8509124532 Sep 15 2015 /fake/file/35
-rw-r--r-- 1 root root 4232 Dec 11 2014 /fake/file/36
-rw-r--r-- 1 root root 8462334652 Apr 9 2015 /fake/file/37
-rw-r--r-- 1 root root 441345893 Apr 9 2015 /fake/file/38
-rw-r--r-- 1 root root 144456171297 Jun 12 2015 /fake/file/39
-rw-r--r-- 1 root root 223299330621 Jun 3 2015 /fake/file/40
-rw-r--r-- 1 root root 1116344491 Nov 11 22:28 /fake/file/41
-rw-r--r-- 1 root root 15265 Apr 15 2014 /fake/file/42

答案1

datesort从 dateutils 包中可以做到这一点:

$ datesort -i '%b %d %Y' -i '%b %d %H:%M' < FILE

诀窍是使用两种输入格式,因为ls对于最近的日期,省略年份并显示时间。

免责声明:我是该工具的作者。

答案2

您不必仅仅因为显示的时间不好看(确实如此)而避免使用 ls:

-c 与 -lt 一起:按 ctime(文件状态信息的最后修改时间)排序并显示; 与 -l 一起:显示 ctime 并按名称排序; 否则:按 ctime 排序,最新的优先

答案3

您可以编写一些小脚本来解析日期字符串,然后按日期排序。有些日期字符串实际上并没有说明哪一年,所以我认为“输入文件写入之前最近的发生”是一个合理的猜测。

快速提出概念证明:

#!/usr/bin/perl
use strict;
use Time::ParseDate;

sub extracttimestamp
{
        my $line = shift;
        my $referencepoint = shift;

        if ($line =~ /^(?:\S+\s+){5}(\S+\s+\S+\s+\S+)\s+/)
        {
                return parsedate($1, NOW => $referencepoint, PREFER_PAST => 1);
        }

        print "FAILED TO PARSE $line\n";
        return -1;
}

my $filename = $ARGV[0];
my $mtime = (stat($filename))[9];

open FILE, "<$filename";
my @list = <FILE>;
close FILE;

my @sorted = sort { extracttimestamp($a, $mtime) <=> extracttimestamp($b, $mtime) } @list;

foreach my $x (@sorted)
{
        print $x;
}

相关内容