Sed удалить все начальные совпадения шаблонов из строки

11

У меня есть следующая строка:

abababtestab

Я пытаюсь выяснить sedвыражение, чтобы удалить все вхождения abиз начала строки, поэтому преобразованная строка должна быть:

testab

Я чувствую, что это должно быть просто, но я действительно ничего не знаю об этом sed.

То, что я до сих пор это:

sed 's/^ab//'

Но это только удаляет первое вхождение ab.

Дэн
источник

Ответы:

16
sed 's/^\(ab\)*//' <in >out

Вы должны сгруппировать это.

echo ababababtestab |
sed 's/^\(ab\)*//'

testab

Некоторые пожилые sedлюди могут не справиться с этим, однако Хотя дублирование подвыражений является функцией BRE, определенной POSIX , некоторые seds не поддерживают ее должным образом. Хотя в некоторых из них ...

echo abababtestab |
sed 's/^\(ab\)\1*//'

... может работать вместо

mikeserv
источник
Именно то, что я искал, спасибо! (Я отмечу как ответ, как только это позволит)
Дэн
Даже 7-е издание sedс 1979 года поддержало его. Это было бы плохой имитацией, чтобы не справиться с группировкой.
Джонатан Леффлер
@JonathanLeffler - см. Обоснование регулярных выражений POSIX , на котором я частично основал это утверждение. Может быть, это предположение, но там есть параграф ... Стандартные разработчики рассматривали общее историческое поведение, которое поддерживалось \n*, но нет \n\{min,max\}. \(...\)*или \(...\)\{min,max\}, как неумышленный результат конкретной реализации, и они поддерживали как дублирование, так и интервальные выражения после подвыражений и обратных ссылок.
mikeserv
@JonathanLeffler: Он также не работает с версией sed из наборов инструментов семейной реликвии.
Cuonglm
@cuonglm - \(ab\)\1*версия работает с семейной реликвией по умолчанию sed, а \(ab\)*версия работает с семейной реликвией SuSv4 sed. По крайней мере, для моей сборки. По общему признанию, я построил свой семейный набор против musl lib C, и поэтому я могу предположить, что это могло заставить его вести себя по-другому. Но обычно, когда указанная функция работает в инструменте семейной реликвии SuSv4, а не в инструменте по умолчанию, это происходит потому, что разработчик сделал это.
mikeserv
6

Другое sed:

sed -e ':1' -e 's/^ab//;t1'

Для каждой строки ввода мы устанавливаем метку :1, а затем выполняем sзамену abв начале строки. Если substitution успешно, test команда ветвится к метке 1, повторяйте работу до тех пор, пока abв начале строки не появится шаблон, мы закончили.

cuonglm
источник
Мои мысли точно. Строго, вам не нужно тестировать: s/^ab//; t1достаточно
Гленн Джекман
@glennjackman: Ах, конечно. Обновил это!
Cuonglm