Search code examples
regexsedreplacecapture

sed - capture a group and replace only one character


I have the following question, a file with pattern like this:

1XYZ00

so the result would be

2XYZ00

I want to change only the first number with another number, for example 9 and not changing anything for the rest of the patern.

I really need to capture this pattern 1XYZ00 and only this one and replace the first number with another one. I this file I can have numbers but with different pattern and those must not be modified.

The OS is CentOS 7.

Here is what I have tested

sed -E 's/1{1}[A-Z]{3}[0-9]{2}/9{1}[A-Z]{3}[0-9]{2}/g' ~/input.txt > ~/output.txt

I also tried with capture group:

sed --debug -E -r 's/1\(1{1}[A-Z]{3}[0-9]{2}\)/9\1/g' ~/input.txt > ~/output.txt

The sed's debug mode tells me that the pattern matches but no replacement is made.

I think I am pretty close, does any expert could help me please ?

Thanks a lot,


Solution

  • $ cat ip.txt
    foo 1XYZ00
    xyz 1 2 3
    hi 3XYZ00
    1XYZ0A
    cool 3ABC23
    
    $ # matches any number followed by 3 uppercase and 2 digit characters
    $ sed -E 's/[0-9]([A-Z]{3}[0-9]{2})/9\1/' ip.txt
    foo 9XYZ00
    xyz 1 2 3
    hi 9XYZ00
    1XYZ0A
    cool 9ABC23
    
    $ # matches digit '1' followed by 3 uppercase and 2 digit characters
    $ sed -E 's/1([A-Z]{3}[0-9]{2})/9\1/' ip.txt
    foo 9XYZ00
    xyz 1 2 3
    hi 3XYZ00
    1XYZ0A
    cool 3ABC23
    

    Issue with OP's attempts:

    • 1{1}[A-Z]{3}[0-9]{2} is same as 1[A-Z]{3}[0-9]{2}
    • Using 9{1}[A-Z]{3}[0-9]{2} in replacement section will give you those characters literally. They don't have any special meaning.
    • s/1\(1{1}[A-Z]{3}[0-9]{2}\)/9\1/ this one does use capture groups but () shouldn't be escaped with -E option active and 1{1} shouldn't be part of the capture group