4

In JS, I can use a function String.prototype.replace() when replacing a submatch in a regular expression. For example:

var x = 'a1b2c3'.replace(/(\d+)/g, (num) => {
    return num*num+1
})
console.log(x)
// 'a2b5c10'

I've tried using sed but it seems that invoking an operator $(()) inside of the replacement is not possible.

$ echo "a1b2c3" | sed 's/\([^0-9]*\)\([0-9]\)\([^0-9]*\)/\1$((\2*\2+1))\3/g'
# Output: a$((1*1+1))b$((2*2+1))c$((3*3+1))

Is there a similar tool or function in bash that has the functionality similar to JS's String.replace()?

0

2 Answers 2

1

The bash shell does support a native regex operator which you can enable with the ~ flag. All you need to do is define a regex, take the captured groups and replace them with the modified values

str='a1b2c3'
re='^.*([0-9]+).*([0-9]+).*([0-9]+).*$'
if [[ $str =~ $re ]]; then
    for match in "${BASH_REMATCH[@]}"; do
        final="${str/$match/$((match*match+1))}"
    done
fi
printf '%s\n' "$final"

The [[ $str =~ $re ]] does the regex match and updates the captured group array ${BASH_REMATCH[@]}. So for each of the element in the order of their appearance, we do the string substitution operator ${str/old/new}. The replacement value in your case is the number multiplied with itself and added by 1.

Add more capturing groups to the regex .*([0-9]+) for subsequent matches.


If not for a pure bash solution above, using an external utility like perl, one could do it as

perl -pe 's/\d+/$&*$&+1/ge' <<<"$str"

The $& refers to the captured digit in the string and the e flag allows do arithmetic operations over the captured groups.

Sign up to request clarification or add additional context in comments.

Comments

1

You can implement this in gawk using match() and substr().

echo "a1b2c3" | awk '{
    head = ""
    tail = $0

    while (match(tail, /[0-9]+/)) {
        num = substr(tail, RSTART, RLENGTH)
        num = num * num + 1
        head = head substr(tail, 1, RSTART-1) num
        tail = substr(tail, RSTART + RLENGTH)
    }

    print head tail
}'

Output

a2b5c10

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.