David Baumgarten
David Baumgarten

Reputation: 19

Using sed to transform json

I am trying to use sed to transform this json:

{
  "terraform_version": "0.14.8",
  "terraform_revision": "",
  "provider_selections": {
    "registry.terraform.io/hashicorp/azuread": "1.3.0",
    "registry.terraform.io/hashicorp/azurerm": "2.47.0",
    "registry.terraform.io/hashicorp/cloudinit": "2.1.0",
    "registry.terraform.io/hashicorp/external": "2.0.0",
    "registry.terraform.io/hashicorp/kubernetes": "2.0.2",
    "registry.terraform.io/hashicorp/local": "2.0.0",
    "registry.terraform.io/hashicorp/null": "3.0.0",
    "registry.terraform.io/hashicorp/template": "2.2.0",
    "registry.terraform.io/hashicorp/tls": "3.0.0"
  },
  "terraform_outdated": false
}

to look like this:

{
  "terraform_version": "0.14.8",
  "terraform_revision": "",
  "provider_selections": "{\"registry.terraform.io/hashicorp/azuread\":\"1.3.0\",\"registry.terraform.io/hashicorp/azurerm\":\"2.47.0\",\"registry.terraform.io/hashicorp/cloudinit\":\"2.1.0\",\"registry.terraform.io/hashicorp/external\":\"2.0.0\",\"registry.terraform.io/hashicorp/kubernetes\":\"2.0.2\",\"registry.terraform.io/hashicorp/local\":\"2.0.0\",\"registry.terraform.io/hashicorp/null\":\"3.0.0\",\"registry.terraform.io/hashicorp/template\":\"2.2.0\",\"registry.terraform.io/hashicorp/tls\":\"3.0.0\"}",
  "terraform_outdated": "false"
}

Essentially, provider_selections should be encapsulated in quotes and the quotes inside of it escaped. I also need the terraform_outdated value to be a string.

I attempted this:

cat jsondata.json | sed 's/{/"{/2' | sed 's/}/"}/1'

but I cannot figure out the rest.

Upvotes: 0

Views: 166

Answers (3)

etsuhisa
etsuhisa

Reputation: 1758

Using sed, it is as following:

sed -r '/: \{/{x;N;:L;N;s/},/},/;TL;s/\"/\\\"/g;x;G;s/\n *//g};s/: ([^\"].*[^,])(,)?$/: \"\1\"\2/' file.json

Expanded to multiple lines

sed -r '
/: \{/{
  x
  N
  :L
    N
    s/},/},/
  TL
  s/\"/\\\"/g
  x
  G
  s/\n *//g
}
s/: ([^\"].*[^,])(,)?$/: \"\1\"\2/
' file.json

However, It is not versatile to use sed for format conversion like the above...

Upvotes: 1

Philippe
Philippe

Reputation: 26602

If you can use python :

#!/usr/bin/env bash
  
python -c "import json,sys
data=json.loads(open(sys.argv[1]).read())
data['provider_selections'] = json.dumps(data['provider_selections'])
print(json.dumps(data))
" data.json

Upvotes: 1

Jetchisel
Jetchisel

Reputation: 7801

If ed is acceptable/available.

#!/usr/bin/env bash

ed -s file.json <<-'EOF'
  g/: {/+1;/},/-1s/\"/\\\"/g
  g/: {/+1;/},/-1s/[[:blank:]]*//
  g/: {/+1;/},/s/[[:blank:]]\{1,\}//
  g/: {/;/},/j
  .,+s/\(.*\) \({\?.*}\?\)/\1 "\2"/
  ,p
  Q
EOF

If the output is correct just change Q to w to edit the file inplace.

Only tested on GNU ed.

Upvotes: 0

Related Questions