使用sed提取特定键的第一个值实例

时间:2017-03-03 00:39:21

标签: string sed extract

从这个字符串(已消毒),我试图从这个有效负载中提取"id"的第一个实例(在这里格式化,但实际上只在一行上):

{
    "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 ": []
}

使用以下sed语句:

`echo $txtauthkey | sed -e 's/^.*"id"[ ]*:[ ]*"//' -e 's/".*//'`

但它会提取"id"的最后一个实例,即"0feeeeeeeeeeeeeeeeeeeeeeeeeeeeee"

2 个答案:

答案 0 :(得分:1)

使用不情愿的量词.*?而不是贪婪的.*。不幸的是,没有sed的味道支持不情愿的量词,但perl确实如此:

`echo $txtauthkey | perl -pe 's/^.*?"id" *: *"//;s/".*//'
  • .*消费尽可能 - 一直到最后 '"id"
  • .*?消费尽可能 little - 这将停留在第一个`'" id"&#39 ;

答案 1 :(得分:0)

如果您有权访问它,使用JSON解析器jq非常简单:

$ jq -r '.result[0].id' infile.json
a4e2a4682e286dea803aaa4d2aff851212c3

使用sed,您可以反转输入并提取"value":"di"的最后一个实例并再次反转:

$ rev infile.json | sed 's/.*"\([^"]*\)"[[:blank:]]*:[[:blank:]]*"di".*/\1/' | rev
a4e2a4682e286dea803aaa4d2aff851212c3

除了sed而且没有别的东西,我想不出比从字符串开头剪掉字符更好的事情,直到它从"id"开始:

$ sed ':a;/^id"/{s/id"[[:blank:]]*:[[:blank:]]*"\([^"]*\).*/\1/;q};s/[^"]*"//;ba' infile.json
a4e2a4682e286dea803aaa4d2aff851212c3

更具可读性:

: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