Shell 按日期排序重复项

Shell 按日期排序重复项,shell,sorting,unix,sh,Shell,Sorting,Unix,Sh,我有一个包含两列元素(id和date)的文件。我想根据id对这些元素进行排序,如果几个元素具有相同的id,它们将根据日期进行排序 我使用了sort-t”“-k2-t”/-k3-k2-k1 file.txt,但这不起作用。 我不知道如何使用字段分隔符 输入文件 01/02/2012 1 02/03/2012 1 04/04/2012 1 01/02/2015 2 02/03/2014 2 04/04/2013 2 输出文件应为: 01/02/2012 1

我有一个包含两列元素(id和date)的文件。我想根据id对这些元素进行排序,如果几个元素具有相同的id,它们将根据日期进行排序

我使用了
sort-t”“-k2-t”/-k3-k2-k1 file.txt
,但这不起作用。 我不知道如何使用字段分隔符

输入文件

01/02/2012 1
02/03/2012 1
04/04/2012 1
01/02/2015 2
02/03/2014 2
04/04/2013 2
输出文件应为:

01/02/2012 1                                                                                                                                                                                      
02/03/2012 1                                                                                                                                                                                      
04/04/2012 1                                                                                                                                                                                     
04/04/2013 2                                                                                                                                                                                      
02/03/2014 2                                                                                                                                                                                     
01/02/2015 2

坦白地说,我很确定你可以用一个复杂的表达式来指示
sort
理解日期,但你真的不应该

这是python中可读的几行代码;差不多

#!/usr/bin/env python2
from dateutil import parser
import sys

class comparable_line(object):
     def __init__(self, line):
         spacepos = line.find(" ")
         if spacepos < 0:
              raise ValueError("line must contain a space")
         self._num = int(line[spacepos+1:])
         self._date = parser.parse(line[:spacepos])

     def __cmp__(self, other):
         """" comparison method that is automatically called by python """"
         if self._num < other._num:
             return -1
         if self._num > other._num:
             return 1
         # at this point we know that the numbers are equal
         if self._date < other._date:
             return -1
         if self._date > other._date:
             return 1
         # totally equal: return equality (0)
         return 0
    def __str__(self):
         return "{num:d} {day:02d}/{month:02d}/{year:4d}".format(self._num, self._date.day, self._date.month, self._date.year)

sortedlines = [comparable_line(l) for l in sys.stdin].sort()
for line in sortedlines:
    print line

会有用的

坦率地说,我很确定你可以用一个复杂的表达式来指示
sort
理解日期,但你真的不应该

这是python中可读的几行代码;差不多

#!/usr/bin/env python2
from dateutil import parser
import sys

class comparable_line(object):
     def __init__(self, line):
         spacepos = line.find(" ")
         if spacepos < 0:
              raise ValueError("line must contain a space")
         self._num = int(line[spacepos+1:])
         self._date = parser.parse(line[:spacepos])

     def __cmp__(self, other):
         """" comparison method that is automatically called by python """"
         if self._num < other._num:
             return -1
         if self._num > other._num:
             return 1
         # at this point we know that the numbers are equal
         if self._date < other._date:
             return -1
         if self._date > other._date:
             return 1
         # totally equal: return equality (0)
         return 0
    def __str__(self):
         return "{num:d} {day:02d}/{month:02d}/{year:4d}".format(self._num, self._date.day, self._date.month, self._date.year)

sortedlines = [comparable_line(l) for l in sys.stdin].sort()
for line in sortedlines:
    print line
会有用的

想法:尝试使用一个字段分隔符(
sort
不处理两个或多个不同的分隔符)

第一个
sed
/
分隔符将空格字符替换为
/
而不是
排序
,下一个
sed
将最后一个
/
替换为空格

我不知道您的日期格式是
DD/MM/yyyyy
MM/DD/yyyyy
,所以您可能希望在
排序中使用repace
-k4-k3-k2-k1
-k4-k3-k1-k2
(我假设是第一个版本)。

想法:尝试使用一个字段分隔符(
排序
不能处理两个或更多不同的分隔符)

第一个
sed
/
分隔符将空格字符替换为
/
而不是
排序
,下一个
sed
将最后一个
/
替换为空格


我不知道您的日期格式是
DD/MM/yyyyy
MM/DD/YYYY
,所以您可能希望在
排序中将
-k4-k3-k2-k1
改为
-k4-k3-k1-k2
(我假设是第一个版本)。

与@uzsolt的答案类似,是一种施瓦茨变换

sed -r 's#([0-9]{2})/([0-9]{2})/([0-9]{4})#\3\2\1 &#' file |
  sort -t " " -n -k 3,3 -k 1,1 |
  cut -d " " -f 2-
第一个命令在行首添加一个更合理的日期:

01/02/2012 1    =>    20120201 01/02/2012 1
然后按字段3和字段1进行简单的数字排序。

然后切断新添加的第一个字段。

这与@uzzolt的答案类似,是一个Schwartzian变换

sed -r 's#([0-9]{2})/([0-9]{2})/([0-9]{4})#\3\2\1 &#' file |
  sort -t " " -n -k 3,3 -k 1,1 |
  cut -d " " -f 2-
第一个命令在行首添加一个更合理的日期:

01/02/2012 1    =>    20120201 01/02/2012 1
然后按字段3和字段1进行简单的数字排序。

然后删除新添加的第一个字段。

您的日期格式太糟糕了。是MM/DD/YYYY(据我所知,美国是地球上唯一使用这种格式的地方,而我们(世界其他地区)通常不喜欢这种格式,但美国确实占主导地位),还是DD/MM/YYYY(相对合理的格式,很遗憾,与美国的格式容易混淆)?@Marcus根据他的预期输出,我相信他使用DD/MM/YYYY。美国和加拿大使用的格式是MM/DD/YYYY:日期有一个标准——我希望每个人都能使用它!你的约会格式太糟糕了。是MM/DD/YYYY(据我所知,美国是地球上唯一使用这种格式的地方,而我们(世界其他地区)通常不喜欢这种格式,但美国确实占主导地位),还是DD/MM/YYYY(相对合理的格式,很遗憾,与美国的格式容易混淆)?@Marcus根据他的预期输出,我相信他使用DD/MM/YYYY。美国和加拿大使用的格式是MM/DD/YYYY:日期有一个标准——我希望每个人都能使用它!如果我们使用GNU sed,您的上一个sed可以简化:替换第三个斜杠:
sed's,/,3'
此外,您可能希望更精确地指定字段:
-k4,4-k3,3-k2,2-k1,1
——如编写的排序所示
-k4,4-k3,4-k2,4-k1,4
。在这里,结果是一样的,但在其他情况下,这可能会咬到你。@glennjackman我使用的是FreeBSD的
sed
-它不支持
3
(数字)标志。那么
sed-E的,(.*)/,\1',
——因为
*
是贪婪的,我们知道我们已经有了最后一个斜杠。如果我们使用GNU sed,您的最后一个sed可以简化:替换第三个斜杠:
sed's,/,3'
。此外,您可能希望更精确地指定字段:
-k4,4-k3,3-k2,2-k1,1
——如书面排序所示
-k4,4-k3,4-k1,4
。在这里,结果是一样的,但在其他情况下,这可能会咬到你。@glennjackman我使用的是FreeBSD的
sed
-它不支持
3
(数字)标志。那么
sed-E的,(.*)/,\1',
-既然
*
是贪婪的,我们知道我们已经有了最后一个斜杠了。