Удалите дубликаты и оставьте только те, за которыми следует определенное слово.

Да, они идентичны.

Я бы предложил первый синтаксис, так как он более лаконичен.

0
30.09.2019, 17:15
2 ответа

Уникальная сортировка сделает это.

$ sort -u input.txt
2019-02-17 not active
2019-02-18 active
2019-02-19 active
2019-02-19 not active
2019-02-20 active
2019-02-21 not active
2019-02-22 not active

Кстати, sort input.txt | uniqделает то же самое, а uniqимеет опцию -fдля пропуска полей при определении уникальности, опции -dи -D, если вы хотите напечатать не -уникальные строки а не только уникальные.


В качестве альтернативы, если вы хотите, чтобы только одна строка вывода на дату и чтобы любая «активная» запись имела приоритет над «неактивной» (или другими )записями:

perl -lane '
  $date=shift @F;
  $day{$date} = join(" ",@F) unless ($day{$date} eq "active");
  END {print $_. " ". $day{$_} for (sort keys %day)}' input.txt
2019-02-17 not active
2019-02-18 active
2019-02-19 active
2019-02-20 active
2019-02-21 not active
2019-02-22 not active

Это создает хэш(%day)с датами в качестве ключей и остальными полями в качестве значений.Текущее или последнее -увиденное значение для любого данного дня заменит более раннее -увиденное значение , если значение для любого данного дня уже не является "активным". В этом случае значение дня не будет заменено.

Когда все входные данные прочитаны, хэш %day сортируется и печатается.

Это более полезно и повторно -применимо, чем полагаться на порядок сортировки второго поля. например, если вы хотите, чтобы «zzzzz» имел приоритет, а не «действие». Также полезно, если второе поле может содержать что-то, что отсортировано перед «действием» (, например. номер)

0
28.01.2020, 03:14

С GNU uniqвы можете сделать

 sort file | uniq -w 10

Опция -wограничивает сравнение 10 символами, поэтому каждая дата сохраняется только один раз. Сортировка заставляет activeпоявляться первым, поэтому он останется.

Если будущие читатели этого вопроса окажутся в системе без GNU uniq, вы можете использовать, например, sed. Классический способ удаления повторяющихся строк —

sed '$!N;/^\(.*\)\n\1$/!P;D'

Шаблон N;P;Dвсегда сохраняет две строки в пространстве шаблона, но печатает только первую, если вторая не совпадает. Мы можем изменить этот скрипт, чтобы проверять наличие дубликатов только в части даты:

sed '$!N;/^\([^ ]*\).*\n\1/!P;D'

Теперь нам нужно только позаботиться о том, чтобы предпочесть activeстроки:

sed '$!N;/^\([^ ]*\).*\n\1/!P;//s/\(.*\)\(\n\).*not.*/\2\1/;D'

Первая часть остается прежней :Печатать только строки после изменения даты (или в последней строке ). Но если дата та же (, то пустой шаблон в адресе //означает повторение последнего шаблона ), обычно вторая строка сохраняется. Но если во второй строке есть not, лучше оставить первую строку(activeили not active), поэтому команда sделает первую строку второй (после пустой строки, которая будет удалена. по Dтак или иначе ).

Я признаю, что это менее элегантно, чем версия GNU, но, по крайней мере, она остается однострочной -.

0
28.01.2020, 03:14

Теги

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