Сортировка по идентификатору, затем сортировка по дате, затем удаление строк, которые имеют более старую дату?

У меня есть несколько файлов с разделителями табуляции.

Каждый файл структурирован так:

ID          Title                                 Rating    Date_Rated

То, что я хочу сделать, это объединить все эти файлы в один и сохранить только последний рейтинг.

file1 может иметь такие данные, как:

70202148    Sherlock Holmes: A Game of Shadows    5         28/12/13

file2 может иметь такие данные, как:

70202148    Sherlock Holmes: A Game of Shadows    4.5       25/12/13

2 ответа

Решение

Предполагая, что поле даты находится в dd/mm/yy Формат следующий должен сделать трюк:

cat file1 file2 ... | \
    sort -t$'\t' -n -k1,1 -k4.7r -k4.4r -k4.1r | sort -t$'\t' -k1,1n -u

Использование инструментов оболочки для этой задачи было бы опасно, так как sort не сможет понять форматы даты. Примером является то, что если вы запустите код Мирослава в приведенном ниже файле, вывод выведет строку с записью даты 28/02/14 что неправильно.

$ cat file.txt 
70202148    Sherlock Holmes: A Game of Shadows    5         28/12/14
70202148    Sherlock Holmes: A Game of Shadows    5         28/02/14
70202148    Sherlock Holmes: A Game of Shadows    5         28/12/13
70202148    Sherlock Holmes: A Game of Shadows    5         28/12/13

Вместо того, чтобы использовать инструменты оболочки, для этого нам нужно использовать языки сценариев / программирования высокого уровня. Для этого вы можете использовать Python, Perl, Ruby или любой другой язык. Ниже Python сценарий, который делает работу.

#!/usr/bin/env python3


import datetime

data = {}

for line in open('file.txt'):

    line = line.strip().split()
    if len(line) == 0:
        continue

    if line[0] not in data:
        date = datetime.datetime.strptime(line.pop(-1), '%d/%m/%y')
        data[line.pop(0)] = {'rating':line.pop(-1), 'year':date, 'title': ' '.join(line[1:]) }
    else:
        date = datetime.datetime.strptime(line.pop(-1), '%d/%m/%y')
        if date > data[line[0]]['year']:
            data[line.pop(0)] = {'rating':line.pop(-1), 'year':date, 'title': ' '.join(line[1:]) }


for val in sorted(data):
    print('{} {} {} {}'.format(val, data[val]['title'], data[val]['rating'], data[val]['year'].strftime('%d/%m/%y')))

Выход:

$ ./filter.py 
70080038 Iron Man 4 18/02/14
70202148 Sherlock Holmes: A Game of Shadows 5 28/12/14
Другие вопросы по тегам