Unix(Solaris)排序的ls -l输出,带有数字名称

时间:2012-08-27 04:47:37

标签: unix sorting ls

给定ls -l目录列表是软件发布版本,如何分类为人类更喜欢的形式?例如:

$ ls -loghF
total 209
drwxr-xr-x   2       3 Jun 18 11:33 12.0.40.0/
drwxr-xr-x   2       3 Aug 24 14:45 13.0.11.10/
drwxr-xr-x   2       3 Jul 13 14:12 13.0.11.4/
drwxr-xr-x   2       3 Jul 26 15:30 13.0.11.5/
drwxr-xr-x   2       4 Jul 27 11:33 13.0.11.6/
drwxr-xr-x   2       3 Aug  3 11:41 13.0.11.7/
drwxr-xr-x   2       3 Aug 10 11:53 13.0.11.8/
drwxr-xr-x   2       3 Aug 17 17:00 13.0.11.9/
drwxr-xr-x   2       3 Aug  3 14:37 13.0.17.0/
drwxr-xr-x   2       3 Aug 13 11:50 13.0.18.0/
drwxr-xr-x   2       3 Aug 17 11:21 13.0.19.0/
drwxr-xr-x   2       3 Jul 28 15:00 13.0.9.1/

期望的结果是:

$ ls -loghF | sort ...
total 209
drwxr-xr-x   2       3 Jun 18 11:33 12.0.40.0/
drwxr-xr-x   2       3 Jul 28 15:00 13.0.9.1/
drwxr-xr-x   2       3 Jul 13 14:12 13.0.11.4/
drwxr-xr-x   2       3 Jul 26 15:30 13.0.11.5/
drwxr-xr-x   2       4 Jul 27 11:33 13.0.11.6/
drwxr-xr-x   2       3 Aug  3 11:41 13.0.11.7/
drwxr-xr-x   2       3 Aug 10 11:53 13.0.11.8/
drwxr-xr-x   2       3 Aug 17 17:00 13.0.11.9/
drwxr-xr-x   2       3 Aug 24 14:45 13.0.11.10/
drwxr-xr-x   2       3 Aug  3 14:37 13.0.17.0/
drwxr-xr-x   2       3 Aug 13 11:50 13.0.18.0/
drwxr-xr-x   2       3 Aug 17 11:21 13.0.19.0/

排序必须跳过每一行的日期部分,然后使用'。'进行数字排序(例如,从12或13开始)。作为字段分隔符。

我想到了两种方法,但是如果它完全支持的话,我对排序-k语法有困难:

(1)跳过前36个字符,然后用'。'作为字段分隔符,在接下来的4个字段中按数字排序。

(2)将字段分隔符作为空格,跳到第7个字段,然后将字段分隔符更改为“。”并在接下来的4个字段中进行数字排序。

备用是一个小的Perl脚本,但不能用Unix排序做这个“简单”的任务吗?

3 个答案:

答案 0 :(得分:2)

这是一个命令行,它使用awk将版本号放在第一位,使用四个数字键进行排序,然后使用cut摆脱前面的临时值:

$ ls -loghF | awk '{ print $7, $0; }' | sort -n -t. -k1,1 -k2,2 -k3,3 -k4,4 | cut -d' ' -f2-
drwxr-xr-x   2       3 Jun 18 11:33 12.0.40.0/
drwxr-xr-x   2       3 Jul 28 15:00 13.0.9.1/
drwxr-xr-x   2       3 Jul 13 14:12 13.0.11.4/
drwxr-xr-x   2       3 Jul 26 15:30 13.0.11.5/
drwxr-xr-x   2       4 Jul 27 11:33 13.0.11.6/
drwxr-xr-x   2       3 Aug  3 11:41 13.0.11.7/
drwxr-xr-x   2       3 Aug 10 11:53 13.0.11.8/
drwxr-xr-x   2       3 Aug 17 17:00 13.0.11.9/
drwxr-xr-x   2       3 Aug 24 14:45 13.0.11.10/
drwxr-xr-x   2       3 Aug  3 14:37 13.0.17.0/
drwxr-xr-x   2       3 Aug 13 11:50 13.0.18.0/
drwxr-xr-x   2       3 Aug 17 11:21 13.0.19.0/

那里的sort命令是从this answer借来的。另一个答案建议sort -V(版本排序),但我的sort版本没有它(你的可能,但所以值得尝试)。版本排序可能特定于较新的GNU coreutils(我的Linux盒子有它,并且排序来自GNU Coreutils 8.5)。

版本排序:

$ ls -loghF | sort -k7,7V
drwxr-xr-x   2       3 Jun 18 11:33 12.0.40.0/
drwxr-xr-x   2       3 Jul 28 15:00 13.0.9.1/
drwxr-xr-x   2       3 Jul 13 14:12 13.0.11.4/
drwxr-xr-x   2       3 Jul 26 15:30 13.0.11.5/
drwxr-xr-x   2       4 Jul 27 11:33 13.0.11.6/
drwxr-xr-x   2       3 Aug  3 11:41 13.0.11.7/
drwxr-xr-x   2       3 Aug 10 11:53 13.0.11.8/
drwxr-xr-x   2       3 Aug 17 17:00 13.0.11.9/
drwxr-xr-x   2       3 Aug 24 14:45 13.0.11.10/
drwxr-xr-x   2       3 Aug  3 14:37 13.0.17.0/
drwxr-xr-x   2       3 Aug 13 11:50 13.0.18.0/
drwxr-xr-x   2       3 Aug 17 11:21 13.0.19.0/

答案 1 :(得分:1)

这不是最快的方法,但解释起来相当简单:

ls -loghF |
awk '{ print $7 " " $0 }' |
sort -t. -k 1,1n -k 2,2n -k3,3n -k 4,4n |
sed 's/^[^ ]* //'

'awk'命令将目录字段复制到行的前面; sort命令只使用一个分隔符(.;我不认为你可以为一行的不同部分使用不同的分隔符),然后按数字顺序显式地对4个数字部分进行排序。然后sed删除在前面添加的字段。

这是“让sort轻松查找密钥”的简单版本,因为拆分输入是sort中昂贵的操作之一。

答案 2 :(得分:1)

仅供参考:这是我最终做的事情 特别感谢:http://www.sysarch.com/Perl/sort_paper.html

$ ls -loghF | perl -e '
use strict;
my @in = <>;
my @out = grep(m|\d+\.\d+\.\d+\.\d+/$|, @in);
print sort {
    my @aa = $a =~
            m|(\d+)\.(\d+)\.(\d+)\.(\d+)/$|;
    my @bb = $b =~
            m|(\d+)\.(\d+)\.(\d+)\.(\d+)/$|;
    $aa[0] <=> $bb[0] or
    $aa[1] <=> $bb[1] or
    $aa[2] <=> $bb[2] or
    $aa[3] <=> $bb[3]
    } @out;
'
drwxr-xr-x   2       3 Jun 18 11:33 12.0.40.0/
drwxr-xr-x   2       3 Jul 28 15:00 13.0.9.1/
drwxr-xr-x   2       3 Jul 13 14:12 13.0.11.4/
drwxr-xr-x   2       3 Jul 26 15:30 13.0.11.5/
drwxr-xr-x   2       4 Jul 27 11:33 13.0.11.6/
drwxr-xr-x   2       3 Aug  3 11:41 13.0.11.7/
drwxr-xr-x   2       3 Aug 10 11:53 13.0.11.8/
drwxr-xr-x   2       3 Aug 17 17:00 13.0.11.9/
drwxr-xr-x   2       3 Aug 24 14:45 13.0.11.10/
drwxr-xr-x   2       3 Aug 29 17:31 13.0.11.11/
drwxr-xr-x   2       3 Aug  3 14:37 13.0.17.0/
drwxr-xr-x   2       3 Aug 13 11:50 13.0.18.0/
drwxr-xr-x   2       3 Aug 17 11:21 13.0.19.0/