unixsedbackreference

back reference with sed command getting unexpected result


File Content

abab102
cdcd103
efef105

I want the username and id separated. Here, abab is user and 102 is id.

I use the command

sed 's/\([a-z]\)\{4\}\([0-9]\)\{3\}/Username:\1 ID:\2/' file.txt

Get this

Username:b ID:2
Username:d ID:3
Username:f ID:5

But I am expecting

Username:abab ID:102
Username:cdcd ID:103
Username:efef ID:105

But using the command

sed -e 's/\([a-z]\)\{4\}/Username:&/' -e 's/\([0-9]\)\{3\}/ID:&/' file2.txt

Output

Username:ababID:102
Username:cdcdID:103
Username:efefID:105

This output is close to what I need, but still I am expecting a blank space between Username:abab ID:102. I want to know why \1 or \2 is not working here.


Solution

  • \([a-z]\) - between ( ) is one letter. If you repeat the \(\) group, back reference goes to the last matched expression. Put all the repetition inside.

    's/\([a-z]\{4\}\)\([0-9]\{3\}\)/Username:\1 ID:\2/'
    

    Ugh, simpler with extended:

    sed -E 's/([a-z]{4})([0-9]{3})/Username:\1 ID:\2/'