给定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排序做这个“简单”的任务吗?
答案 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/