11

I have the following line:

abababtestab

I'm trying to figure out a sed expression to remove all occurrences of ab from the beginning of the line so the transformed line should be:

testab

I feel like this should be simple, but I really don't know anything about sed.

What I have so far is:

sed 's/^ab//'

But this only removes the first occurrence of ab.

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

You should group it.

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

testab

Some older seds may not handle that very well, though. Though sub-expression duplication is a POSIX-specified feature of BRE, some seds don't properly support it. In some of those, though...

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

...might work instead.

  • Exactly what I was looking for thanks! (I'll mark as answer once it lets me) – Dan Jul 8 '15 at 14:03
  • Even 7th Edition sed from circa 1979 supported it. It would have to be an inferior imitation not to handle the grouping. – Jonathan Leffler Jul 8 '15 at 15:04
  • @JonathanLeffler - see the POSIX Regular Expression Rationale, which is, partly, what I based the statement on. Maybe it's an assumption, but there's a paragraph there... The standard developers regarded the common historical behavior, which supported \n*, but not \n\{min,max\}. \(...\)*, or \(...\)\{min,max\}, as a non-intentional result of a specific implementation, and they supported both duplication and interval expressions following subexpressions and back-references. – mikeserv Jul 8 '15 at 15:25
  • @JonathanLeffler: It also doesn't work with sed version from heirloom toolchests. – cuonglm Jul 8 '15 at 16:13
  • @cuonglm - the \(ab\)\1* version works w/ the default heirloom sed, and the \(ab\)* version works w/ the SuSv4 heirloom sed. At least, it does for my build. Admittedly, I built my heirloom set against musl lib C, and so I can imagine that might cause it to behave differently. But usually when a specified feature works in an heirloom SuSv4 heirloom tool but not in the default tool, it is because the dev made it do. – mikeserv Jul 8 '15 at 16:33
6

Another sed:

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

With each line of input, we set up a label :1, then doing substitution ab at start of line. If substitution successfully, test command branch to label 1, redo the work until no ab pattern appeared at the start of line, we're done.

  • My thoughts exactly. Strictly, you don't need to test: s/^ab//; t1 is sufficient – glenn jackman Jul 8 '15 at 14:30
  • @glennjackman: Ah, of course. Updated it! – cuonglm Jul 8 '15 at 14:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.