按bash中的多个列排序

时间:2016-12-19 21:20:30

标签: linux bash sorting reverse alphabetical

我有一个包含2列的文件,“名称”和“年龄”,如下所示:

Alex,  15
Mary,  12
Alex,  28
Zoe,   16
Alex,  17

我将使用sort -t ',' -k1,1 filename.txt按字母顺序按第一列排序,但如果有相同的名称,我希望第二列按照它们在原始文件中的方式进行排序,例如这样:

Alex,  17
Alex,  28
Alex,  15
Mary,  12
Zoe,   17

我该怎么做?

6 个答案:

答案 0 :(得分:2)

从后面读取文件,按第一列排序,-s在相同值的情况下保留顺序

tac filename.txt | sort -k1,1 -s
...
Alex,  17
Alex,  28
Alex,  15
Mary,  12
Zoe,   16

答案 1 :(得分:1)

似乎我误解了你的问题。我找不到一个神奇的命令,但是一个小脚本可能会起作用:

#! /bin/bash
declare names_sorted=$(cut -d, -f1 filename.txt | sort -k1,1 | uniq)
for name in $names_sorted ; do
    grep "$name," filename.txt | tac
done

快速解释:

  1. 首先我们汇总了已排序的名单:$names_sorted
  2. next(假设名称不包含空格),我们从原始列表中grep每个名称,并使用命令tac
  3. 恢复该顺序

    希望这次是你想要的; - )

答案 2 :(得分:1)

不确定你为什么要这样做!但你可以很容易地在python中完成它(不会保留空格):

import sys
entries    = [tuple(map(lambda x: x.strip(), line.strip().split(","))) for line in sys.stdin]
names,ages = zip(*entries)

def compare(a,b):
    res = cmp(a[0], b[0])
    if (res == 0):
        return -cmp(ages.index(a[1]), ages.index(b[1]))
    return res

print "\n".join("%s %s" % (name,age) for name,age in sorted(entries, cmp=compare))

答案 3 :(得分:1)

sort -t ',' -k1,1 -k2,2r filename.txt

sort -t ',' -k1,1 -k2r,2 filename.txt

输出结果为:

Alex,  28
Alex,  17
Alex,  15
Mary,  12
Zoe,   16

说明:-t是指定字段分隔符,-k可用于指定字段的开始和停止位置,我们可以为其添加单个字母OPTS用于排序的字段,例如r表示反转比较结果。

答案 4 :(得分:0)

这应该是你想要的:

sort -k1,1 -k2,2 filename.txt

答案 5 :(得分:0)

tac filename.txt | sort -t"," -k1,1 -s

说明:

  • tac将以相反的顺序对输出进行排序。
  • -t","定义字段定界符。
  • -k1,1将排序列限制为仅第一列。
  • -s保留已排序行中的顺序。