Search code examples
regexvimsed

How can I translate a regex within vim to work with sed?


I have a string that exists within a text file that I am trying to modify with regex.

"configuration_file_for_wks_33-40"

and I want to modify it so that it looks like this

"configuration_file_for_wks_33-40_6ks"

Within vim I can accomplish this with the following regex command

%s/33-\(\d\d\)/33-\1_6ks/ 

But if I try to pass that regex command to sed such as

sed 's/33-\(\d\d\)/33-\1_6ks/' input_file.json

The string is not changed, even if I include the -e parameter.

I have also tried to do this using ex as

echo '%s/33-\(\d\d\)/33-\1_6ks/' | ex input_file.json

If I use

sed  's/wks_33-\(\d\d\)*/wks_33-\1_6ks/' input_file.json

then I get

configuration_file_for_wks_33-_6ks40

For that, I've tried various different escaping patterns without any luck.

Can someone help me understand why this changes are not working?


Solution

  • vim has a different syntax for regular expressions (which is even configurable). Unfortunately, sed doesn't understand \d (see https://unix.stackexchange.com/a/414230/304256). With -E, you can match digits with [0-9] or [[:digit:]]:

    $ sed -E 's/33-[0-9][0-9]/&_6ks/'
    configuration_file_for_wks_33-40_6ks
    

    Note that you can use & in the replacement for adding the entire matched string.

    So why is this:

    $ sed  's/wks_33-\(\d\d\)*/wks_33-\1_6ks/' input_file.json
    configuration_file_for_wks_33-_6ks40
    

    Here, (\d\d)* is simply matched 0 times, so you replace wks_33- by wks_33-_6ks (\1 is a zero-length string) and 40 remains where it was before.