В машине с AIX без < code> PERL я должен отфильтровать отчеты, которые будут считать дублированными, если у них будет тот же id и если они были зарегистрированы между периодом четырех часов.
Я осуществил этот фильтр, используя < code> AWK и работа вполне прилично, но мне нужно решение намного быстрее:
< pre> # Generar Листа де Дюпликадо awk ' НАЧНИТЕ { FS =" " } /OK/{ старые [8$] = f [8$]; f [8$] = mktime (4$, 3$, 2$, 5$, 6$, 7$); x [8$] ++; } /OK/& & x [8$] > 1 & & f [8$] - старые [8$] < 14400 { печать 0$; } функционируйте mktime (y, m, d, гд, mm, ss) { возвратите ss + (mm*60) + (hh*3600) + (d*86400) + (m*2592000) + (y*31536000); } ' the.big.file.txtКакие-либо предложения? Там пути состоят в том, чтобы улучшить окружающую среду (предварительно загружающий файл или что-то как этот)?
Входной файл уже сортирован.
С исправлениями, предложенными < href =" https://stackoverflow.com/questions/6475/faster-way-to-find-duplicates-conditioned-by-time#6869" > jj33 я сделал новую версию с лучшей обработкой дат, все еще придерживаясь сдержанной позиции для слияния большего количества операций:
< pre> awk ' НАЧНИТЕ { FS =" "; SECSPERMINUTE=60; SECSPERHOUR=3600; SECSPERDAY=86400; разделение (" 0 31 59 90 120 151 181 212 243 273 304 334" DAYSTOMONTH, " "); разделение (" 0 366 731 1096 1461 1827 2192 2557 2922 3288 3653 4018 4383 4749 5114 5479 5844 6210 6575 6940 7305" DAYSTOYEAR, " "); } /OK/{ старые [8$] = f [8$]; f [8$] = mktime (4$, 3$, 2$, 5$, 6$, 7$); x [8$] ++; } /OK/& & x [8$] > 1 & & f [8$] - старые [8$] < 14400 { печать 0$; } функционируйте mktime (y, m, d, гд, mm, ss) { d2m = DAYSTOMONTH [интервал (m)]; если ((m > 2) & & (((y % 4 == 0) & & (y % 100! = 0)) || (y % 400 == 0))) { d2m = d2m + 1; } d2y = DAYSTOYEAR [y - 1999]; возвратите ss + (mm*SECSPERMINUTE) + (hh*SECSPEROUR) + (d*SECSPERDAY) + (d2m*SECSPERDAY) + (d2y*SECSPERDAY); } 'Это походит на работу для фактической базы данных. Даже что-то как SQLite могло, вероятно, помочь Вам обоснованно хорошо здесь. Большой проблемой, которую я вижу, является Ваше определение " в 4 hours". That' s проблема раздвижного окна, что означает Вас can' t просто квантуют все данные к 4-часовым сегментам..., Вы должны вычислить весь " nearby" элементы для любого элемента отдельно. Тьфу.
Если Ваш файл данных содержит все Ваши отчеты (т.е. он включает отчеты, у которых нет dupicate ids в файле), Вы могли предварительно обработать его и произвести файл, который только содержит отчеты, у которых есть дубликат (ids).
Если это верно, это уменьшило бы размер файла, который Вы должны обработать со своей программой AWK.
Как входной файл сортирован? Как, кошка file|sort, или сортированный через единственную определенную область или несколько областей? Если несколько областей, что области и что заказ? Кажется, что области часа - 24-часовые часы, не 12, правильно? Все области даты/времени, с нулевой подкладкой (был бы 9:00 быть " 9" или " 09"?)
Не принимая во внимание работу похоже, что у Вашего кодекса есть проблемы с границами месяца, так как это предполагает, что все месяцы 30 дней длиной. Возьмите эти две даты 2008-05-31/12:00:00 и 2008-06-01:12:00:00. Те на расстоянии в 24 часа, но Ваш кодекс производит тот же временной код для оба (63339969600)
Я думаю, что Вы должны были бы рассмотреть високосные годы. Я didn' t делают математику, но я думаю в течение високосного года с твердым кодексом 28 дней на февраль, сравнение полудня на 2/29 и полдень на 3/1 привело бы к той же двойной отметке времени как прежде. Хотя это похоже на Вас didn' t осуществляют его как этот. Они способ, которым Вы осуществили его, я думаю, что у Вас все еще есть проблема, но it' s между датами на 12/31$leapyear и 1/1$leapyear+1.
Я думаю, что у Вас могли бы также быть некоторые столкновения во время изменений времени, если Ваш кодекс должен обращаться с часовыми поясами, которые обращаются с ними.
Файл doesn' t действительно, кажется, сортирован любым полезным способом. I' m предполагающий, что область 1$ является своего рода статусом (" OK" you' проверка ре). Так it' s сортированный рекордным статусом, тогда днем, затем МЕСЯЦ, ГОД, ЧАСЫ, МИНУТЫ, СЕКУНДЫ. Если бы это был год, месяц, то день, я думаю, мог бы быть некоторой оптимизацией там. Все еще мог бы быть всего лишь мой brain' s вход в различное направление прямо сейчас.
Если есть небольшое количество двойных ключей в пропорции к общему количеству линий, я думаю, что Ваш лучший выбор состоит в том, чтобы уменьшить файл Ваши awk работы сценария, чтобы просто сделать дубликаты ключа (как Дэвид сказал). Вы могли также предварительно обработать файл, таким образом, единственные линии представляют,/OK/линии. Я думаю, что сделал бы это с трубопроводом, где первый awk сценарий только печатает линии с двойными ID, и второй awk сценарий - в основном тот выше, но оптимизированный, чтобы не искать/OK/и со знанием, что любой существующий ключ является двойным ключом.
Если Вы знаете заранее это все, или большинство линий повторит ключи, it' s, вероятно, не стоящий питания с. I' d стиснули зубы и пишут его в C. Тонны больше линий кодекса, намного быстрее, чем awk сценарий.
На многих unixen Вы можете получить вид к виду конкретной колонкой или область. Таким образом, сортируя файл ID, и затем датой, Вы больше не должны держать ассоциативное множество того, когда Вы в последний раз видели каждый ID вообще. Весь контекст находится там в заказе файла.
На моем Mac, у которого есть вид ГНУ, it' s:
sort -k 8 < input.txt > output.txt
к виду на идентификационной области. Вы можете сортировать на второй области также, говоря (например), 8,3 вместо этого, но ТОЛЬКО 2 областях. Таким образом, стиль Unix time_t метка времени не мог бы быть плохой идеей в файле - it' s легкий к виду, и экономит Вам всем те вычисления даты. Кроме того, (снова, по крайней мере, у ГНУ awk), есть mktime функция, который делает time_t для Вас от компонентов.
AnotherHowie, я думал, что целая предварительная обработка могла быть сделана с видом и uniq. Проблема состоит в том что OP' s данные, кажется, разграниченная запятая и (Солярис 8' s) uniq doesn' t позволяют Вам, любой путь определяет рекордный сепаратор, так там wasn' t супер чистый способ сделать предварительную обработку, используя стандартные инструменты Unix. Я don' t думают, что это было бы немного быстрее так I' m не собирающийся искать точные варианты, но Вы могли сделать что-то как:
cut -d, -f8 <infile.txt | sort | uniq -d | xargs -i grep {} infile.txt >outfile.txt
That' s не очень хороший, потому что это выполняет grep за каждую линию, содержащую двойной ключ. Вы могли, вероятно, массажировать продукцию uniq в единственный regexp, чтобы питаться к grep, но выгода только будет известна, если посты OP ожидаемое отношение линий, содержащих подозреваемый, сделают дубликаты ключа к полным линиям в файле.