0

I'm very new to awk, I'm trying to do the following in an environment that doesn't support grep -P and doesn't have Perl installed either.

Given I have a list of env variables starting with a prefix, I want to generate an argument list based on those variables, without using the prefix.

So, for example, if I have

PREFIX_VARIABLE_1=100
PREFIX_VARIABLE_2=500

I'd like to generate

 --set service.VARIABLE_1=100 --set service.VARIABLE_2=500

I've came up with

 env | awk 'match($0, /PREFIX_.*/) { substr($0, RSTART+8, RLENGTH) ; split($0, parts, "=") ; printf "--set service.%s=%s ", parts[1], parts[2] }'

but this doesn't strip the prefix, substr is not being used I guess

With grep -P I can do it:

 env | grep -oP '(?<=PREFIX_)(.*)' | awk 'split($0, parts, "=") { printf "--set service.%s=%s ", parts[1], parts[2] }'

Any idea how to chain/pipe multiple awk functions properly? Thanks

1
  • For gawk using option --lint is a good idea while developing, BTW.
    – U. Windl
    Commented Apr 29, 2021 at 21:09

3 Answers 3

4

Your code, with newlines for readability

env | awk '
    match($0, /PREFIX_.*/) {
        substr($0, RSTART+8, RLENGTH) 
        split($0, parts, "=") 
        printf "--set service.%s=%s ", parts[1], parts[2]
    }
'

substr works just fine. You're not doing anything with the return value. substr by itself does not modify $0.

First, I'd recommend making the regex more specific, so that it finds PREFIX_VAR=something and not some_other_var=$PREFIX_VAR

Then, since you know what PREFIX is, I'd suggest you don't need to use RSTART etc.

Last, use = as the field separator to make it easier to work with the varname.

env | awk -F= '$1 ~ /^PREFIX_/ {printf "--set service.%s=%s ", substr($1,8), $2}'

This code, like yours, will not properly handle the variable value containing an equal sign. To join fields 2..NF in awk is a bit of a hassle:

env | awk '
    function join (fstart, fend, separator,      i, result) {
        for (i = fstart; i <= fend; i++) 
            result = result $i (i == fend ? "" : separator)
        return result
    }
    $1 ~ /^PREFIX_/ {
        var = substr($1, 8)
        value = join(2, NF, "=")
        printf "--set service.%s=%s ", var value
    }
'
2

Using cat file in place of your env command:

$ cat file | awk 'sub(/^PREFIX_/,"--set service."){out=out sep $0; sep=OFS} END{print out}'

--set service.VARIABLE_1=100 --set service.VARIABLE_2=500
0

It is also possible to do it without using awk. Just demonstrating another way

 while read -r env
   do 
     [[ $env == *PREFIX_* ]] && envs+=("--set service.${env#*_}")
   done < <(env)       
 printf '%s ' "${envs[@]}"

So here you read each line that has PREFIX_ in it and append it to an array variable by using +=. The ${env#*_} makes sure that i.e:

PREFIX_VARIABLE_1=100

becomes

VARIABLE_1=100

See String Manupulations for more.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.