Using sed to replace numbers

33,645

In "modern" regexes, + has a special meaning — it means "one or more" (just like how * means "zero or more") — so to match an actual plus sign, you need to use \+. Since you apparently prefer not to wrap your sed-script in quotes, you would write it as \\+:

echo "bla 18934750 + wwv_flow_id.offset bla" | sed -E s/\ \\+\ wwv_flow_id.offset/blabla/

though I think it will make your life easier if you abandon that preference, and write:

echo "bla 18934750 + wwv_flow_id.offset bla" | sed -E 's/ \+ wwv_flow_id.offset/blabla/'

Quoting your argument will also address your back-reference issue, whereby Bash is translating \1 to 1:

echo "bla 18934750 + wwv_flow_id.offset bla" | sed -E 's/([0-9]+) /\1/'

though if you still prefer to stick with your non-quoted-sed-script style, you could write \\1:

echo "bla 18934750 + wwv_flow_id.offset bla" | sed -E s/\([0-9]+\)\ /\\1/
Share:
33,645
Rob van Wijk
Author by

Rob van Wijk

Updated on October 01, 2020

Comments

  • Rob van Wijk
    Rob van Wijk over 3 years

    I'd like to replace some numbers in a file with the result of a calculation using the found number, and like to use sed on MacOSX. I've tried a lot of variants and now know I have to use -E to use modern instead of basic regular expression.

    Some examples:

    echo "bla 18934750 + wwv_flow_id.offset bla" | sed s/\ +\ wwv_flow_id.offset/blabla/
    

    gives

    bla 18934750blabla bla
    

    So without the -E, it finds and replaces fixed text. But with the -E, it doesn't:

    echo "bla 18934750 + wwv_flow_id.offset bla" | sed -E s/\ +\ wwv_flow_id.offset/blabla/
    

    gives

    bla 18934750 + wwv_flow_id.offset bla
    

    In other words: no match and no change in the text. The ultimate goal is to find the number that precedes the fixed text " + wwv_flow_id.offset" and use that number and subtract a fixed number (say 750) from it, so the end result becomes:

    bla 18934000 + wwv_flow_id.offset bla
    

    And for that I need at least back references, which also don't work like I expected, because

    echo "bla 18934750 + wwv_flow_id.offset bla" | sed -E s/\([0-9]+\)\ /\1/
    

    gives

    bla 1+ wwv_flow_id.offset bla
    

    I hope some regex guru can help me out here.


    UPDATE

    With the help of ruakh, this is what I've got now:

    echo "bla 18934750 + wwv_flow_id.offset bla" | sed -E 's/([0-9]+) \+ wwv_flow_id.offset/(\1-750) \+ wwv_flow_id.offset/'
    

    which returns:

    bla (18934750-750) + wwv_flow_id.offset bla
    

    The bonus question now is, how to turn this into

    bla 18934000 + wwv_flow_id.offset bla
    




    UPDATE 2

    I managed to achieve my desired result by combining sed with awk, like this:

    echo "bla 18934750 + wwv_flow_id.offset bla" | sed -E 's/([0-9]+)([ ]*)\+([ ]*)wwv_flow_id.offset/~\1~\2\+\3wwv_flow_id.offset/' | awk -F~ '{print $1 $2-750 $3}'
    

    (I know for sure there are no ~ tokens on the original line)