replacing only part of matched pattern in sed

19,211

Try:

$ echo 'abcd 12345 qwerty asdfg' | sed -E 's/([[:digit:]]) ([[:alpha:]])/\1,\2/g'
abcd 12345,qwerty asdfg

Notes:

  1. We added -E to get extended regex syntax.

  2. [:digit:] and [:alpha:] are used in place of 0-9 and A-Z in order to be unicode safe.

  3. Parens are used to create groups and we can reference in the replacement text. In our case, \1 references the number and \2 references the letter.

Share:
19,211

Related videos on Youtube

John1024
Author by

John1024

Updated on September 18, 2022

Comments

  • John1024
    John1024 over 1 year

    For tens of thousands of lines with the same structure, i want to go (e.g.) from here:

    abcd 12345 qwerty asdfg
    

    ...to here:

    abcd 12345,qwerty asdfg
    

    ...with

    sed 's/[0-9]\ [A-Z]/,/g'
    

    I can match the rigth space plus both its surrounding characters (5 q), but in the replacement i get (obviously):

    abcd 1234,werty asdfg
    

    Also, i'd prefer to perform this in the linux shell

    How could i match and replace for each and every line only that space which is preceded by a digit and followed by an alphabet letter? would you suggest me another tool (or even approach) instead to get this done?

  • ryantuck
    ryantuck almost 4 years
    This was a really clear explanation of the various bits of the solution.
  • Admin
    Admin almost 2 years
    in my case, capturing groups have to be escaped to work correctly: s|\(anything\)|\1|g, or else I have error message: sed: -e expression #1, char 73: invalid reference \1 on `s' command's RHS
  • Admin
    Admin almost 2 years
    @user11153 Try sed -E 's|(anything)|\1|g' (with upper-case E in -E) instead of sed 's|(anything)|\1|g'. The -E option turns on "extended regular expressions" which eliminates the need for those backslashes.