Reputation: 23
From this string (sanitized), I'm trying to extract the first instance of the "id"
from this payload (formatted here, but is actually all on one line):
{
"result": [{
"id": "a4e2a4682e286dea803aaa4d2aff851212c3",
"name": "test.com",
"status": "active",
"paused": false,
"type": "partial",
"development_mode": 0,
"verification_key": "12312312-123123",
"original_name_servers": ["dns1.test.com", "dns2.test.com"],
"original_registrar": null,
"original_dnshost": "register",
"modified_on": "2017-02-24T17:59:59.080278Z",
"created_on": "2017-01-31T20:27:03.395683Z",
"meta": {
"step": 4,
"wildcard_proxiable": false,
"custom_certificate_quota": 0,
"page_rule_quota": 3,
"phishing_detected": false,
"multiple_railguns_allowed": false
},
"owner": {
"type": "organization",
"id": "12312123123",
"name": "Test"
},
"permissions": ["#analytics:read", "#billing:edit", "#billing:read", "#cache_purge:edit", "#dns_records:edit", "#dns_records:read", "#lb:edit", "#lb:read", "#logs:read", "#organization:edit", "#organization:read", "#ssl:edit", "#ssl:read", "#waf:edit", "#waf:read", "#zone:edit", "#zone:read", "#zone_settings:edit", "#zone_settings:read"],
"plan": {
"id": "0feeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"name": "Free Website ",
"price ": 0,
"currency ": "USD ",
"frequency ": "",
"is_subscribed ": true,
"can_subscribe ": false,
"legacy_id ": "free ",
"legacy_discount ": false,
"externally_managed ": false
}
}],
"result_info": {
"page": 1,
"per_page ": 20,
"total_pages": 1,
"count ": 1,
"total_count ": 1
},
"success ": true,
"errors ": [],
"messages ": []
}
using following sed statement:
`echo $txtauthkey | sed -e 's/^.*"id"[ ]*:[ ]*"//' -e 's/".*//'`
but it extracts the last instance of "id"
, ie "0feeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
Upvotes: 1
Views: 81
Reputation: 52506
If you have access to it, this is very simple with the JSON parser jq:
$ jq -r '.result[0].id' infile.json
a4e2a4682e286dea803aaa4d2aff851212c3
With sed, you could reverse the input and extract the last instance of "value":"di"
and reverse it again:
$ rev infile.json | sed 's/.*"\([^"]*\)"[[:blank:]]*:[[:blank:]]*"di".*/\1/' | rev
a4e2a4682e286dea803aaa4d2aff851212c3
And with sed and nothing else, I can't think of anything better than shaving of characters from the beginning of the string until it starts with "id"
:
$ sed ':a;/^id"/{s/id"[[:blank:]]*:[[:blank:]]*"\([^"]*\).*/\1/;q};s/[^"]*"//;ba' infile.json
a4e2a4682e286dea803aaa4d2aff851212c3
More readable:
:a # Label to branch to
/^id"/ { # If the line starts with id"
# Extract value of "id" key
s/id"[[:blank:]]*:[[:blank:]]*"\([^"]*\).*/\1/
q # Quit - we are done
}
s/[^"]*"// # Remove characters up and including next double quote
ba # Branch to label
Upvotes: 0
Reputation: 425358
Use a reluctant quantifier .*?
rather than a greedy one .*
. Unfortunately, no flavour of sed
supports reluctant quantifier, but perl
does:
`echo $txtauthkey | perl -pe 's/^.*?"id" *: *"//;s/".*//'
.*
consumes as much as possible - all the way to the last '"id"
.*?
consumes as little as possible - which will stop at the first `'"id"'Upvotes: 1