Да, они идентичны.
Я бы предложил первый синтаксис, так как он более лаконичен.
Уникальная сортировка сделает это.
$ 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» имел приоритет, а не «действие». Также полезно, если второе поле может содержать что-то, что отсортировано перед «действием» (, например. номер)
С 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, но, по крайней мере, она остается однострочной -.