以不同顺序进行多次排序

时间:2011-10-22 10:21:46

标签: linux unix sorting

我有这样的数据

HOS05 23/12/2008 10AM  
HOS06 15/12/2008 2PM  
HOS62 29/12/2008 10AM  
HOS64 23/12/2008 2PM  
HOS70 26/12/2008 10AM  
ZFT01 06/12/2008 10AM  
HOS73 11/12/2008 2PM  
MHOS0 05/12/2008 10AM  
MHOS0 20/12/2008 2PM  
MHOS0 27/12/2010 2PM  
MHOS0 11/12/2008 10AM  
MHOS0 30/12/2009 2PM
      ^^    ^^^^

我必须按两个偏移排序,用^ s表示。

第一个突出显示的偏移应按ASC顺序排序,然后以DESC顺序突出显示。所以我喜欢这个

sort -k 1.6,1.8 date.txt  | sort -k 1.14,1.17 -r > final.txt

输出:

MHOS0 27/12/2010 2PM  
MHOS0 30/12/2009 2PM  
ZFT01 06/12/2008 10AM  
MHOS0 20/12/2008 2PM
MHOS0 11/12/2008 10AM
MHOS0 05/12/2008 10AM
HOS73 11/12/2008 2PM
HOS70 26/12/2008 10AM
HOS64 23/12/2008 2PM
HOS62 29/12/2008 10AM
HOS06 15/12/2008 2PM
HOS05 23/12/2008 10AM

这工作正常,但我需要单一排序命令。 有什么建议吗?

2 个答案:

答案 0 :(得分:2)

我在联机帮助页中发现了这个多汁的花絮:

POS is F[.C][OPTS], where F is the field number and C the character position in the field;  both
   are  origin  1.   If  neither -t nor -b is in effect, characters in a field are counted from the
   beginning of the preceding whitespace.  OPTS is one  or  more  single-letter  ordering  options,
   which override global ordering options for that key.  If no key is given, use the entire line as
   the key.

这是第一次拍摄:

  

sort -k 1.6,1.8 date.txt | sort -k 1.14,1.17 -r

那怎么样:

sort  -k 2.7r,2.10 -k 2.1,2.2 date.txt

记住[*],字段由空格分隔,并从1开始计算,因此您的日期字段为字段2.

[*]不要记住这个!我在说辞。只需在使用不熟悉的命令时阅读联机帮助页。字段的编号方式是不同命令之间差异很大的细节之一。

答案 1 :(得分:1)

我不知道如何使用单个sort命令来实现此目的。当我必须解决这类问题时,我使用perl脚本。类似于以下简单脚本的东西将为您完成工作(并允许您灵活地按您想要的任何字段排序,无论您想要的顺序):

#!/usr/bin/perl

@lines = ();
while (<>) { push(@lines, $_); }

@sorted = sort {
  $a1 = substr($a, 0, 6);
  $ayear = substr($a, 12, 4);
  $b1 = substr($b, 0, 6);
  $byear = substr($b, 12, 4);
  if ($ayear == $byear) { return $b1 cmp $a1; }
  else { return $byear cmp $ayear; }
} @lines;

print @sorted;

然后,当然,

$ perl sorter.perl < data.txt

perl sort文档位于http://perldoc.perl.org/functions/sort.html