Sed usuwa wszystkie początkowe dopasowania wzorca z linii

11

Mam następującą linię:

abababtestab

Próbuję wymyślić sedwyrażenie, aby usunąć wszystkie wystąpienia abz początku wiersza, więc przekształcona linia powinna być:

testab

Wydaje mi się, że to powinno być proste, ale tak naprawdę nic nie wiem sed.

Do tej pory mam:

sed 's/^ab//'

Ale to usuwa tylko pierwsze wystąpienie ab.

Dan
źródło

Odpowiedzi:

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

Powinieneś to zgrupować.

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

testab

Niektóre starsze seds może nie obsługiwać że bardzo dobrze, choć. Chociaż powielanie podwyrażeń jest funkcją BRE zdefiniowaną przez POSIX , niektóre sednie obsługują go poprawnie. Jednak w niektórych z nich ...

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

... może zamiast tego działać.

mikeserv
źródło
Właśnie tego szukałem dzięki! (Oznaczę jako odpowiedź, gdy tylko mi na to pozwoli)
Dan
sedWspierała go nawet 7. edycja z około 1979 roku. Musiałoby to być gorsze naśladownictwo, aby nie zajmować się grupowaniem.
Jonathan Leffler,
@JathanathanLeffler - zobacz uzasadnienie wyrażenia regularnego POSIX , na którym częściowo opierałem to stwierdzenie. Może to założenie, ale jest tam akapit ... Standardowi programiści rozważali wspólne zachowanie historyczne, które wspierało \n*, ale nie \n\{min,max\}. \(...\)*lub \(...\)\{min,max\}, jako nie zamierzony wynik konkretnej implementacji, i obsługiwały one zarówno duplikację, jak i wyrażenia interwałowe po podwyrażeniach i referencjach wstecznych.
mikeserv
@JonathanLeffler: To również nie działa z wersją sed z zestawów narzędzi dziedzicznych.
cuonglm
@cuonglm - \(ab\)\1*wersja działa z domyślnym spadkiem sed, a \(ab\)*wersja działa z spadkiem SuSv4 sed. Przynajmniej tak jest w przypadku mojej wersji. Trzeba przyznać, że mój zestaw pamiątkowy zbudowałem na musl lib C, więc mogę sobie wyobrazić, że może to spowodować inne zachowanie. Ale zwykle, gdy określona funkcja działa w narzędziu dziedziczenia SuSv4, ale nie w narzędziu domyślnym, dzieje się tak dlatego, że zrobił to deweloper.
mikeserv
6

Kolejny sed:

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

Z każdą linią wejściową tworzymy etykietę :1, a następnie wykonujemy substitution abna początku linii. Jeśli substytucja się powiedzie, test gałąź polecenia do etykiety 1, ponów pracę, dopóki abna początku wiersza nie pojawi się żaden wzór, gotowe.

Cuonglm
źródło
Dokładnie moje myśli. Ściśle mówiąc, nie trzeba testować: s/^ab//; t1wystarczy
glenn jackman
@glennjackman: Ach, oczywiście. Zaktualizowałem to!
cuonglm