0

I have this variable called var, whose value is as shown below.

$ echo $var   
{'active_production_dc':'sc-tx2','standby_production_dc':'sc_tx3','active_integration_dc':'int_tx3','standby_integration-dc':'int_va1'}

From this output , I need to extract the values of

'active_production_dc', 
'standby_production_dc', 
'active_integration_dc' and 
'standby_integration_dc' into four different variables.

The below one just extracting keys. I want to extract the keys into variables.

printf "%s" "$var" | awk 'NR>1 && NR%2' RS="({'|'.'|'})"

if I

echo $active_production_dc

then it should return

sc-tx2

Something like that. Basically the value for active_production_dc should be saved inside the variable.

2
  • please post the regular expressions you tried and failed, along with output/errors Commented Jul 25, 2016 at 5:43
  • link Commented Jul 25, 2016 at 21:28

3 Answers 3

1

Answer for original question

Let's start with your variable:

$ echo "$var"
{'active-production-dc':'sc-tx2','standby-production-dc':'sc-tx3','active-integration-dc':'int-tx3','standby-integration-dc':'int-va1'}

Using jq

jq does not accept the string as is. We must first replace the single-quotes with double-quotes. Then we can extract the keys:

$ echo "$var" | sed 's/'\''/"/g' | jq keys
[
  "active-integration-dc",
  "active-production-dc",
  "standby-integration-dc",
  "standby-production-dc"
]

Using awk

Using awk to extract the keys:

$ printf "%s" "$var" | awk 'NR%2==0' RS="({'|'.'|'})"
active-production-dc
standby-production-dc
active-integration-dc
standby-integration-dc

Using awk to extract the values that correspond to those keys:

$ printf "%s" "$var" | awk 'NR>1 && NR%2' RS="({'|'.'|'})"
sc-tx2
sc-tx3
int-tx3
int-va1

Answer for revised question

For the revised question, we need a new var:

$ echo "$var"
{'active_production_dc':'sc-tx2','standby_production_dc':'sc_tx3','active_integration_dc':'int_tx3','standby_integration_dc':'int_va1'}

We can create shell variables named after the keys like this:

$ while IFS=":" read -r -d, key val; do declare "$key=$val"; done < <(echo "$var" | sed "s/[{}']//g; s/$/,/")

When this is done the keys and values are accessible:

$ echo "$active_production_dc"
sc-tx2

Alternatively, and probably preferably, we can make the keys and values available in bash via an associative array. Use:

declare -A a
while IFS=":" read -r -d, key val
do
    a["$key"]="$val"
done < <(echo "$var" | sed "s/[{}']//g; s/$/,/")

When this is run, using the value for var in the revised question, then the resulting a contains the keys and values:

$ declare -p a
declare -A a='([standby_integration_dc]="int_va1" [active_production_dc]="sc-tx2" [active_integration_dc]="int_tx3" [standby_production_dc]="sc_tx3" )'

An individual value can be accessed via its key:

$ echo "${a[active_production_dc]}"
sc-tx2
Sign up to request clarification or add additional context in comments.

7 Comments

The sed is useful as a demonstration, but to be safe, you (the OP) should fix whatever is producing the value of var in the first place. sed can't distinguish between single quotes that are used to quote the keys and values, and single quotes that might be embedded in the value.
I am unable to execute . It is saying broken pipe error. Can you put complete code
@user3479901 I just copy-and-pasted the code from my answer to my shell and it works for me. If you continue to get a broken pipe error, please tell me which command it happens on and let me see the complete error message.
I edited the question. Could you please re-check it?
@user3479901 I have added those features to the revised answer.
|
0

Using grep -P you can do:

arr=($(grep -Po '(?<=[{,])[a-zA-Z0-9-]+' <<< "$s"))

# print resulting array
printf "%s\n" "${arr[@]}"
active-production-dc
standby-production-dc
active-integration-dc
standby-integration-dc

However your input appears to be a JSON and you should consider using jq to parse it reliably.

4 Comments

I need like this. I am able to extract using AWK . printf "%s" "$var" | awk 'NR>1 && NR%2' RS="({'|'.'|'})" Or if I echo $active-production-dc, then it should return sc-tx2 Something like that. Basically the value for "active-production-dc" should be saved inside the variable.
You cannot have a variable name active-production-dc in Unix as hyphen is not allowed in variable names
Yes. Its a point. Shall we extract 'active-production-dc', 'standby-production-dc', 'active-integration-dc' and 'standby-integration-dc' values into four different variables?
It is better to work with arrays. If you have BASH 4+ then you can use associative arrays as well
0

A second on using jq to parse the JSON, but if you are required to parse it in bash, then a second option is an array, controlling the IFS (internal field separator) and parameter expansion with substring removal. Use jq in practice:

#!/bin/bash

var="{'active-production-dc':'sc-tx2','standby-production-dc':'sc-tx3',\
'active-integration-dc':'int-tx3','standby-integration-dc':'int-va1'}"

IFS=$','
a=( $(echo "$var") )

for ((i = 0; i < ${#a[@]}; i++)); do 
    b=${a[i]}
    b=${b#*\{}
    b=${b%\}*}
    a[i]="${b%:*}"
done

printf "%s\n" ${a[@]}

Output

$ bash parsevar.sh
'active-production-dc'
'standby-production-dc'
'active-integration-dc'
'standby-integration-dc'

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.