3

I've got problem with removing part of string between two patterns with sed. I've always got last PATTERN-2 in line:

test.txt:

PATTERN-1xxxxPATTERN-2aaa
PATTERN-1xxxxPATTERN-2fffPATTERN-1zzzzPATTERN-2gggPATTERN-1zzzzPATTERN-2
PATTERN-1xxxxPATTERN-2bbb

cmd

sed 's/PATTERN-1.*PATTERN-2//g' test.txt

the result of above is

aaa

bbb

but I would like to have

aaa
fffggg
bbb

Is possible to find PATTERN-2 which is closest to PATTERN-1?

  • 5
    FYI it's easy in regex implementations that support a non-greedy qualifier such as perl's ? i.e. perl -pe 's/PATTERN-1.*?PATTERN-2//g' test.txt – steeldriver Jan 11 '17 at 20:56
  • @steeldriver thank you very much. It works as expected – Maciej Jan 11 '17 at 21:11
  • 1
    @steeldriver Make your comment the answer for the OP – JRFerguson Jan 11 '17 at 21:30
3

As @steeldriver points out, it is easy if you have non-greedy regexps. If not, you can do it with a loop, like this:

sed ':a;s/PATTERN-2/\n/;s/PATTERN-1.*\n//;ta' test.txt

This works because we know there are no newlines in the middle of any line. It would also work with any other character that does not occur in any line, e.g. §.

  • this also work : sed 's/PATTERN-2/\n/g; s/PATTERN-1.*\n//Mg;' – mug896 Jan 18 '17 at 14:26
1

If you want to use only sed try like below

sed 's/PATTERN-1[^P]*PATTERN-2//g' test.txt
0

In your example, the .* matches stuff that you want to keep.

You can capture that stuff and replace it back by using:

sed 's/PATTERN-1\(.*\)PATTERN-2/\1/g' test.txt

Everything between the brackets gets stored in the first capture buffer and \1 substitute in the value of that buffer.

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.