**Tips:**遇见一个有趣的sort命令问题,很有意思,这里记录一下,顺便也再复习一下sort命令。

有意思的例子

  • 要求:将以下文本_按字母排序,_和-之间的按数字升序,-之后的按数字降序排列,不能破坏原本每行的数据,只对上下顺序排列.
  • 文本sort.txt如下
1
2
3
4
5
6
7
8
9
def_99-55
def_99-11
def_123-100
abc_456-100
abc_123-100
def_123-10
abc_456-10
abc_123-1
xzy_789-0
  • 解答
  • 脚本如下
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
cat sort.txt |sed s/_/-/ |sort -t"-" -k1,1 -k2,2n -k3,3nr |sed s/-/_/
#说明:先将分隔符替换为统一,然后以-为分割符对第一字段按基础排序,第二字段按数字排序,第三字段按数字降序排序
#-k1,1这种表达方式是只对本域进行排序是最准确的表达,类似还有-k1.2,1.2表示仅对第一列第二个字符排序,1,1这种表达表示的是一个完整域,如果直接写-k1那就表示从1到最后一个域,这样表述的是不准确的
#输出如下
abc_123-100
abc_123-1
abc_456-100
abc_456-10
def_99-55
def_99-11
def_123-100
def_123-10
xzy_789-0

sort命令回顾

  • 基础选项
  • 常规选项(参考:http://man.linuxde.net/sort)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#usage: sort [选项] [参数]
-b:忽略每行前面开始出的空格字符;
-c:检查文件是否已经按照顺序排序;
-d:排序时,处理英文字母、数字及空格字符外,忽略其他的字符;
-f:排序时,将小写字母视为大写字母;
-i:排序时,除了040至176之间的ASCII字符外,忽略其他的字符;
-m:将几个排序号的文件进行合并;
-M:将前面3个字母依照月份的缩写进行排序;
-n:依照数值的大小排序;
-o<输出文件>:将排序后的结果存入制定的文件;
-r:以相反的顺序来排序;
-t<分隔字符>:指定排序时所用的栏位分隔字符;
+<起始栏位>-<结束栏位>:以指定的栏位来排序,范围由起始栏位到结束栏位的前一栏位
  • 关于古老的+-选定域的说明 sort官方有如下说明(摘自孙愚的博客)

    On older systems, sort’ supports an obsolete origin-zero syntax +POS1 [-POS2]‘ for specifying sort keys. POSIX 1003.1-2001 (*note Standards conformance::) does not allow this; use `-k’ instead. 原来,这种古老的表示方式已经被淘汰了,以后可以理直气壮的鄙视使用这种表示方法的脚本喽! (为了防止古老脚本的存在,在这再说一下这种表示方法,加号表示Start部分,减号表示End部分。最最重要的一点是,这种方式方法是从0开始计数的, 以前所说的第一个域,在此被表示为第0个域。以前的第2个字符,在此表示为第1个字符