Sed удалить все между 2 шаблонами, но не включая шаблоны - PullRequest
0 голосов
/ 13 мая 2018

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

Я хотел бы удалить все, что находится между 1 и несколькими другими возможными шаблонами, но не включая сами шаблоны.Пары шаблонов приведены только для одной строки, а не для нескольких строк.

например,

:1543453 Brown Fox
:789 123456 Cat
:abcdef Yellow Duck

до

:Brown Fox
:Cat
:Yellow Duck

Таким образом, первым шаблоном для сопоставления является ":"а второе - «коричневый» или «кошачий» или «желтый»

1 Ответ

0 голосов
/ 13 мая 2018

Есть грубая сила и невежество, которые иногда хорошо работают:

sed -e 's/^:.* Brown/:Brown/' \
    -e 's/^:.* Cat/:Cat/' \
    -e 's/^:.* Yellow/:Yellow/' \
    data-file.txt

Возможно, вы сможете использовать «расширенные регулярные выражения» с параметрами -E (BSD, Mac, Linux) или -r (только для Linux):

sed -E 's/^:.* (Brown|Cat|Yellow)/:\1/' data-file.txt

Оба дают желаемый результат для данных выборки.

Обратите внимание, что используемый .* является жадным. С учетом входного файла:

:1543453 Brown Fox
:789 123456 Cat
:abcdef Yellow Duck
:quantum mechanics eat Yellow Ducks for being yellow (but leave Yellow Dafodils alone)

оба скрипта выдают:

:Brown Fox
:Cat
:Yellow Duck
:Yellow Dafodils alone)

Вам потребуется Perl или sed, улучшенные с помощью PCRE (Perl-совместимые регулярные выражения) или какой-либо другой программы, чтобы избежать жадности. Например:

$ perl -n -e 'print if s/^:.*? (Brown|Cat|Yellow)/:\1/' data-file.txt
:Brown Fox
:Cat
:Yellow Duck
:Yellow Ducks for being yellow (but leave Yellow Dafodils alone)
$
...