2

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

$ ls -loghF
共计 209
drwxr-xr-x 2 18 年 6 月 3 日 11:33 12.0.40.0/
drwxr-xr-x 2 8 月 24 日 14:45 13.0.11.10/
drwxr-xr-x 2 13 年 7 月 3 日 14:12 13.0.11.4/
drwxr-xr-x 2 7 月 26 日 15:30 13.0.11.5/
drwxr-xr-x 2 7 月 27 日 11:33 13.0.11.6/
drwxr-xr-x 2 月 3 日 8 月 3 日 11:41 13.0.11.7/
drwxr-xr-x 2 10 年 8 月 3 日 11:53 13.0.11.8/
drwxr-xr-x 2 17 年 8 月 3 日 17:00 13.0.11.9/
drwxr-xr-x 2 8 月 3 日 14:37 13.0.17.0/
drwxr-xr-x 2 13 年 8 月 3 日 11:50 13.0.18.0/
drwxr-xr-x 2 17 年 8 月 3 日 11:21 13.0.19.0/
drwxr-xr-x 2 7 月 28 日 15:00 13.0.9.1/

期望的结果是:

$ ls -loghF | 种类 ...
共计 209
drwxr-xr-x 2 18 年 6 月 3 日 11:33 12.0.40.0/
drwxr-xr-x 2 7 月 28 日 15:00 13.0.9.1/
drwxr-xr-x 2 13 年 7 月 3 日 14:12 13.0.11.4/
drwxr-xr-x 2 7 月 26 日 15:30 13.0.11.5/
drwxr-xr-x 2 7 月 27 日 11:33 13.0.11.6/
drwxr-xr-x 2 月 3 日 8 月 3 日 11:41 13.0.11.7/
drwxr-xr-x 2 10 年 8 月 3 日 11:53 13.0.11.8/
drwxr-xr-x 2 17 年 8 月 3 日 17:00 13.0.11.9/
drwxr-xr-x 2 8 月 24 日 14:45 13.0.11.10/
drwxr-xr-x 2 8 月 3 日 14:37 13.0.17.0/
drwxr-xr-x 2 13 年 8 月 3 日 11:50 13.0.18.0/
drwxr-xr-x 2 17 年 8 月 3 日 11:21 13.0.19.0/

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

我想到了两种方法,但是如果完全支持 sort -k 语法,我会遇到困难:

(1) 跳过前 36 个字符,然后使用 '.' 作为字段分隔符,对接下来的 4 个字段进行数字排序。

(2) 以字段分隔符为空格,跳到第7个字段,然后将字段分隔符更改为'.' 并对接下来的 4 个字段进行数字排序。

替代方案是一个小的 Perl 脚本,但 Unix 排序不能完成这个“简单”任务吗?

4

3 回答 3

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 -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/
于 2012-08-27T05:17:04.167 回答
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 18 年 6 月 3 日 11:33 12.0.40.0/
drwxr-xr-x 2 7 月 28 日 15:00 13.0.9.1/
drwxr-xr-x 2 13 年 7 月 3 日 14:12 13.0.11.4/
drwxr-xr-x 2 7 月 26 日 15:30 13.0.11.5/
drwxr-xr-x 2 7 月 27 日 11:33 13.0.11.6/
drwxr-xr-x 2 月 3 日 8 月 3 日 11:41 13.0.11.7/
drwxr-xr-x 2 10 年 8 月 3 日 11:53 13.0.11.8/
drwxr-xr-x 2 17 年 8 月 3 日 17:00 13.0.11.9/
drwxr-xr-x 2 8 月 24 日 14:45 13.0.11.10/
drwxr-xr-x 2 8 月 29 日 17:31 13.0.11.11/
drwxr-xr-x 2 8 月 3 日 14:37 13.0.17.0/
drwxr-xr-x 2 13 年 8 月 3 日 11:50 13.0.18.0/
drwxr-xr-x 2 17 年 8 月 3 日 11:21 13.0.19.0/
于 2012-08-31T04:29:00.390 回答
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.

于 2012-08-27T05:19:58.343 回答