krex
krex

Reputation: 345

Extract a named value from pair in a comma separate list

I'm trying to extract the value of a variable by name (var1,var2, or var3) from a string of comma separated variables in bash:

var1=foo,var2=bar,var3=baz 

I would also like to protect against the case that duplicates exist since the variable is set in an upstream script. In the event there exists a duplicate variables I would like to return the value of the first instance only. So the following example would return 0:

var1=0,var2=baz,var3=foo,var1=2

I would like to restrict the value to one of 0, 1 or 2. So, validate using something like [0-2]{1}.

Example String:

export labels="zone_index=1,node_type=infra,customer=internal"

My solution which seems to work but seems rather kludgy:

echo "$labels" | grep -oE -m1 'zone_index=[0-2]{1}' | cut -f2 -d= | head -n 1

Which will output 1 from the example string. Is there a more elegant and/or robust solution?

Upvotes: 0

Views: 60

Answers (1)

Inian
Inian

Reputation: 85550

You don't need any third party tools to make this work, just the native shell built-ins would be sufficient. The shell does provide a built-in regex support with its ~ operator (from bash v3.0 onwards)

re='zone_index=([[:digit:]]{1,}).*'

if [[ $labels =~ $re ]]; then
    printf '%s\n' "${BASH_REMATCH[1]}"
fi

This regex will work for all the cases you've listed.

  • For the case when when the search string occurring in the first

    labels="zone_index=1,node_type=infra,customer=internal"
    [[ $labels =~ $re ]] && printf '%s\n' "${BASH_REMATCH[1]}"
    1
    
  • For the case when when the search string is duplicated

    labels="zone_index=1,node_type=infra,zone_index=2,customer=internal"
    [[ $labels =~ $re ]] && printf '%s\n' "${BASH_REMATCH[1]}"
    1
    
  • For the case when when the search string is not in the start

    labels="node_type=infra,customer=internal,zone_index=2"
    [[ $labels =~ $re ]] && printf '%s\n' "${BASH_REMATCH[1]}"
    2
    

Upvotes: 1

Related Questions