Если вы хотите удалить только все повторяющиеся строки yyyy-mm-dd, то
% sed '/^yyyy-mm-dd/,$ { n ; /^yyyy-mm-dd/d }' srcfile
Will use per-minute statistics
Stats from 2016-06-26 00:00:00 to 2016-06-26 23:59:00
yyyy-mm-dd hh:mm:ss
6/26/2016 0:01:00
6/26/2016 0:03:00
6/26/2016 0:01:00
6/26/2016 0:01:00
6/26/2016 0:02:00
6/26/2016 0:03:00
Если вы хотите удалить все повторяющиеся строки, то это немного халтурно и неэффективно, но работает и довольно легко понимать. (Вы можете оптимизировать второй sed | grep, но так легче читать, ИМХО).
% sed -n '1,/^yyyy-mm-dd/p' srcfile ; sed '1,/^yyyy-mm-dd/d' srcfile | grep -v ^yyyy-mm-dd | sort -u
Will use per-minute statistics
Stats from 2016-06-26 00:00:00 to 2016-06-26 23:59:00
yyyy-mm-dd hh:mm:ss
6/26/2016 0:01:00
6/26/2016 0:02:00
6/26/2016 0:03:00
Правильный инструмент для этого - awk. Он позволяет вам выразить логику простым способом: установите переменную seen
при первом просмотре шаблона и пропустите строки, соответствующие шаблону, если он уже был замечен. Если строка не пропущена, распечатайте ее.
awk '/^yyyy-mm-dd[ \t]+hh:mm:ss$/ {if (seen) next; ++seen}
1 {print}'
Это можно сократить, но это становится более загадочным.
awk '!(/^yyyy-mm-dd[ \t]+hh:mm:ss$/ && !(seen++))'
sed -e '0,/^yyyy-mm-dd\s\+hh:mm:ss$/!{/^yyyy-mm-dd\s\+hh:mm:ss$/d}'
Диапазон 0, / pattern /
(функция GNU sed) совпадает до первого вхождения, поэтому 0, / pattern /!
запускает содержимое {...}
в оставшейся части файла, удаляя все последующие совпадения.
GNU ed
поддерживает числовое смещение адресов регулярных выражений, поэтому вы можете адресовать диапазон от / pattern / + 1
] в конец файла $
. Затем вы можете удалить любые строки, соответствующие одному и тому же регулярному выражению в этом диапазоне, как g // d
. Наконец, напишите измененный файл и выйдите.
ed file << EOF
/^yyyy-mm-dd/+1,$ g//d
wq
EOF
или эквивалентно
printf '/^yyyy-mm-dd/+1,$ g//d\nwq\n' | ed file