Home > database >  Replace unknow string between two strings in bash
Replace unknow string between two strings in bash

Time:01-12

i want to replace a unknown string between two strings.

(1(...) 2(...) 3(...))

I use:

sed -i "s/2(.*)/2(new)/g"

but i'm getting. (It take the last ')')

(1(hello) 2(new)

And i want :

(1(...) 2(new) 3(...))

Someone can help me please ?

CodePudding user response:

Try:

echo '(1(...) 2(...) 3(...))' | sed 's/2\((\.*)\)/2(new)/g'

You need to escape the brackets that you are using. to match

Update: From Benjamin W's comment

echo '(1(...) 2(TIM) 3(...))' | sed -E 's/2\([^)]*\)/2(new)/g'

CodePudding user response:

I've tried finding hack solutions for non-greedy pattern matching with sed, but have found that perl usually seems to get the job done much easier.

Unless you have a specific constraint with using only sed, you could:

echo "(1(...) 2(...) 3(...))" | perl -pe "s/2(.*?)/2(new)/g"

The only difference in the regex is the ? non-greedy modifier after the .*, which matches the first ).

The command line options are detailed here. Reference for non-greedy modifier is here.

CodePudding user response:

sed uses greedy matching so OP's attempt - 2(.*) - is going to match the 1st literal 2( plus the longest string that ends with ); consider the following where our match starts with the first 2( and runs to the last ):

$ echo '(1(...) 2(...) 3(...) 2(abc) 4(...)) more stuff' | sed 's/2(.*)/2(new)/'
(1(...) 2(new) more stuff

To limit the match to the first matching ) there are a few approaches, one idea is to be explicit about what does and does not match, consider:

$ echo '(1(...) 2(...) 3(...) 2(abc) 4(...)) more stuff' | sed 's/2([^)]*)/2(new)/'
(1(...) 2(new) 3(...) 2(abc) 4(...)) more stuff

In this the case we use 2([^)]*) which says to match on 2( followed by any number of characters that are not a ) ([^)]*) followed by a ).

To match on all non-greedy occurrences of 2(...) (where the ... means any non-) character) we can add the global qualifier on the end of the sed script, eg:

$ echo '(1(...) 2(...) 3(...) 2(abc) 4(...)) more stuff' | sed 's/2([^)]*)/2(new)/g'
(1(...) 2(new) 3(...) 2(new) 4(...)) more stuff
  •  Tags:  
  • Related