I need to parse json which contains spaces in string in it, but the output value is truncated at spaces.
My Initial.json
file is:
{
"WorkspaceName":"aaa bbb ccc ddd eee",
"ReportFileName":"xxx yyy zzz",
"StageName":"sit uat prod"
}
My current shell code is:
InitialFile=$JsonPath/deployment/configuration/Initial.json
data=$(cat $InitialFile | sed -r 's/",/"/' | egrep -v '^[{}]' | sed 's/"//g' | sed 's/:/=/1')
declare $data
echo WorkspaceName is_$WorkspaceName
echo ReportFileName is_$ReportFileName
echo StageName is_$StageName
The result is:
WorkspaceName is_aaa
ReportFileName is_xxx
StageName is_sit
The expected reuslt is aaa bbb ccc ddd eee
, xxx yyy zzz
, sit uat prod
instead of aaa
, xxx
, sit
.
How to achieve it? I'm not very familiar with shells, any advice would be greatly appreciated.
Update:
I using following code to resolve this issue:
WorkspaceName=$(grep -o '"WorkspaceName": "[^"]*' configuration/Initial.json | grep -o '[^"]*$')
ReportFileName=$(grep -o '"ReportFileName": "[^"]*' configuration/Initial.json | grep -o '[^"]*$')
StageName=$(grep -o '"StageName": "[^"]*' configuration/Initial.json | grep -o '[^"]*$')
As you can see, this solves the problem, but it doesn't seem perfect, I need to get each variable in the json separately, there will be a lot of repeated statements, when there are many variables in the json, this will be a Very troublesome, so is there a way to simplify it?
CodePudding user response:
Using sed
$ InitialFile="${JsonPath}/deployment/configuration/Initial.json"
$ data=$(sed -En 's/^[^"]*"([^"]*)":"([^"]*).*$/\1 is_\2/p' "$InitialFile")
$ echo "$data"
WorkspaceName is_aaa bbb ccc ddd eee
ReportFileName is_xxx yyy zzz
StageName is_sit uat prod
CodePudding user response:
1st solution(GNU awk
): With GNU awk
you can try following solution, written and tested with your shown samples only.
awk -v RS='"[^"]*":"[^"]*",?' '
RT{
sub(/":"/,OFS,RT)
gsub(/^"|",?$/,"",RT)
print RT
}
' Input_file
2nd solution: If jq
is allowed you can simply do following command. Which OP is saying is not in OP's system but adding it as a variant here.
jq -r 'to_entries[] | "\(.key) \(.value)"' Input_file
With shown samples output will be as follows:
WorkspaceName aaa bbb ccc ddd eee
ReportFileName xxx yyy zzz
StageName sit uat prod
CodePudding user response:
You could use sed and regexp:
eval $(sed -n -e 's/^.*"\(.*\)":\(".*"\).*$/\1=\2/p' $InitialFile)
sed
will take the filename as an argument-n
will make sed not print per default-e 's/<match pattern>/<output>/
a sed command to search and replace (live test).p
in case of matching pattern the output is printedeval
will evaluate the output as if you would have written it at the prompt. In this case assigning values to some vars.
I think the code above is shorter and better in several ways, but it could of course be done your way with some adjustment, or in several other ways. The main issue with your code is that the assignment needs to be one string, not several. So your code produces this:
WorkspaceName=aaa bbb ccc ddd eee
while it should be:
WorkspaceName="aaa bbb ccc ddd eee"