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

364
quickbooks

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

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

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 
0
Вероятно, следует указать, что я могу сделать 'cat file1 file2> join', чтобы объединить файлы; тогда я могу сделать 'sort join -k1 -n', чтобы отсортировать его по столбцу ID; но я не понял, как сделать все остальное. quickbooks 9 лет назад 0
Всегда ли даты имеют форму «дд / мм / гг», или некоторые из них могут быть «дд / м / гг», «д / мм / гг» или «д / м / гг»? G-Man 9 лет назад 0

2 ответа на вопрос

1
Miroslav Koškár

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

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

Using shell tools for this task would be dangerous as sort will not be able to understand date formats. An example is that if you run Miroslav's code in the below file the output will print the line with date record 28/02/14 which is wrong.

$ 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 

Instead of using shell tools we need to use high level scripting/programming languages for this. You can use Python, Perl, Ruby or any other language for this. Below is a Python script which does the job.

#!/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'))) 

Output:

$ ./filter.py 70080038 Iron Man 4 18/02/14 70202148 Sherlock Holmes: A Game of Shadows 5 28/12/14 
Я согласен с тем, что использование Python - лучший выбор, так как он более гибкий и все. Тем не менее, я не уверен, что вы заметили, что поля разделены табуляцией. Если учесть это, вы увидите, что `sort` будет отлично работать с некоторыми ограничениями (например, с фиксированным форматом даты), а также не очень заботится о возможности иметь несколько строк с одинаковыми датами (сделать сортировку стабильной может быть одна подход). Miroslav Koškár 9 лет назад 0

Похожие вопросы