Unix сортировка, с первичным и вторичным ключами - PullRequest
14 голосов
/ 07 июля 2010

Я бы хотел отсортировать файл по нескольким полям.Пример файла, разделенного табуляцией:

a   1   1.0
b   2   0.1
c   3   0.3
a   4   0.001
c   5   0.5
a   6   0.01
b   7   0.01
a   8   0.35
b   9   2.3
c   10  0.1
c   11  1.0
b   12  3.1
a   13  2.1

И я хотел бы отсортировать его в алфавитном порядке по полю 1 (с -d), а когда поле 1 совпадает, отсортировать по полю 3 (с -g опция).

A не удалось это сделать.Мои попытки были (с реальным символом TAB вместо <TAB>):

cat tst | sort -t"<TAB>" -k1 -k3n
cat tst | sort -t"<TAB>" -k1d -k3n
cat tst | sort -t"<TAB>" -k3n -k1d

Ничего из этого не работает.Я не уверен, что сортировка вообще способна это сделать.Я напишу скрипт для обхода, поэтому мне просто интересно, есть ли решение, использующее только sort .

Ответы [ 2 ]

12 голосов
/ 07 июля 2010

В руководстве приведены некоторые примеры.

В соответствии с комментарием Зседера, это работает:

sort -t"<TAB>" -k1,1d -k3,3g

Вкладка теоретически должна работать так же, как это sort -t"\t".

Если ни один из вышеперечисленных способов не работает с разделителями табуляцией, это уродливое решение:

TAB=`echo -e "\t"`
sort -t"$TAB"
0 голосов
/ 07 июля 2010

Вот скрипт Python, который вы можете использовать в качестве отправной точки:

#!/usr/bin/env python2.6

import sys
import string

def main():
    fname = sys.argv[1]
    data = []
    with open(fname, "rt") as stream:
        for line in stream:
            line = line.strip()
            a, b, c = line.split()
            data.append((a, int(b), float(c)))
    data.sort(key=my_key)
    print data


def my_key(item):
    a, b, c = item
    return c, lexicographical_key(a)


def lexicographical_key(a):
    # poor man's attempt, should use Unicode classification etc.
    return a.translate(None, string.punctuation)


if __name__ == "__main__":
    main()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...