Pass the matched value to the function and replace the return value

How do I get Bash to match the regex, but instead of replacing the value with a constant string, it will instead pass the corresponding value to the function and then get the value to replace with the return value of the function.

Something like the following pseudocode, which replaces each match [a-d]

with the same character, but in uppercase:

function uppercase() { echo ${1^^}; }
string="abcdefgh123cbazyz"
echo ${string//[a-d]/uppercase()}
# output: ABCDef123CBAzyz

      

I am not proprietary, any language that is usually installed on a Unix system (for example sed

, awk

or even the limited regex support built into it bash

) can be used.

+3


source to share


5 answers


Bash cannot use user-defined functions inside a parameter extension .

To accomplish what you want, use case-modification pattern matching :

string="abcdefgh123cbazyz"
echo ${string^^[a-d]}

      



Output:

ABCDefgh123CBAzyz

      

+4


source


You can use Perl for this:

perl -lape 's/([a-d])/`uppercase $1`/eg' <<< "$string"

      

but this would require an executable script named uppercase

. Perl flag e

(eval) executed the command in a match when there is a match.



Another way via sed:

function uppercase() { 
    echo ${1^^} 
}
export -f uppercase
string="abcdefgh123cbazyz"
echo "echo $(sed 's/\([a-d]\)/$(uppercase \1)/g' <<< "$string")" | sh

      

+1


source


Use tr

:

echo abcdefgh123cbazyz | tr '[a-d]' '[A-D]'

      

Or sed

:

echo abcdefgh123cbazyz | sed -r 's|[a-d]|\U&|g'

      

Output:

ABCDefgh123CBAzyz

      

Update

Callback with Ruby

:

puts "abcdefgh123cbazyz".gsub(/[a-d]/){ |m| m.upcase }

      

Callbak with Python

:

import re

s = "abcdefgh123cbazyz"

def repl(m):
    return m.upper()

print(re.sub('\[\[:(.+?):\]\]', repl, s))

      

Callback with Perl

:

my $s = "abcdefgh123cbazyz";
$s =~ s/([a-d])/uc($1)/eg;
print "${s}\n";

      

Output:

ABCDefgh123CBAzyz

      

0


source


In Perl, you can grab a group and pass it to a subroutine like this using the flag e

:

perl -pe 'sub callback { return uc $_[0] } s/([a-d])/callback $1/eg' <<<"$string"

      

Result for your string:

ABCDefgh123CBAzyz

      

Here I just introduced my own wrapper around an existing function uc

that returns converts letters to uppercase. You can change the body of the routine to do whatever you want.

0


source


FWIW this is how you would do it in GNU awk (for the 4th argument to split ()):

$ cat tst.awk                                                
function uppercase(str) { return toupper(str) }
{
    split($0,flds,/[a-d]/,seps)
    for (i=1;i in flds; i++) {
        printf "%s%s", flds[i], uppercase(seps[i])
    }
    print ""
}

$ echo "abcdefgh123cbazyz" | gawk -f tst.awk
ABCDefgh123CBAzyz

      

or with any awk:

$ cat tst.awk                                                
function uppercase(str) { return toupper(str) }
{
    while ( match($0,/[a-d]/) ) {
        printf "%s%s", substr($0,1,RSTART-1), uppercase(substr($0,RSTART,RLENGTH))
        $0 = substr($0,RSTART+RLENGTH)
    }
    print
}

$ echo "abcdefgh123cbazyz" | awk -f tst.awk
ABCDefgh123CBAzyz

      

0


source







All Articles