0

I have a string:

{"testExecIssue":{"id":"1234","key":"KEY-6548","self":"site.com/rest/api/2/issue/68795"},"testIssues":{"success":[{"id":"465644","key":"KEY-6555","self":"site.com/rest/api/2/issue/68799"}]}}

I am trying to get "key" of "success", and I want sed to output just KEY-6555.

echo "{"testExecIssue":{"id":"1234","key":"KEY-6548","self":"site.com/rest/api/2/issue/68795"},"testIssues":{"success":[{"id":"465644","key":"KEY-6555","self":"site.com/rest/api/2/issue/68799"}]}}" > file
sed -e 's/.*testIssues":{"success":[{"id":"[0-9]","key":"\(KEY-[0-9]\).*/\1/' file

running sed outputs original echo, with [0-9] filled in:

{testExecIssue:{id:1234,key:KEY-6548,self:site.com/rest/api/2/issue/68795},testIssues:{success:[{id:465644,key:KEY-6555,self:site.com/rest/api/2/issue/68799}]}}

Now, I am either extremely dumb and outputting file, or using .* .* wrong. Where am I making a mistake and how should I correct it?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Pedro Gonzalez
  • 95
  • 2
  • 11
  • 2
    the current sed isn't matching nothing and so changing nothing, hence the same input line. try to quote `echo` with single quotes, the current one is removing all the double quotes inside; change also `[0-9]` to `[0-9]\+` or you'd match just one char. – Joao Morais Oct 07 '20 at 14:44
  • 7
    Have you considered using `jq` for this job? `jq -r '.testExecIssue.key' – Charles Duffy Oct 07 '20 at 14:47
  • 4
    ...and not just shorter, but more reliable. A lot of JSON encoders don't guarantee key order -- it can just fall out of what order strings hash into -- so you don't know that `id` will always come before `key`. Similarly, the producer changes their settings so there's whitespace in your string, and the sed code fails then too. Use `jq` or another JSON-aware tool and those things aren't problems. – Charles Duffy Oct 07 '20 at 14:59

2 Answers2

2

For JSON use a proper JSON parser like jq. jq has a full fledged query language that lets you easily find the data you need:

$ jq -r '.testIssues.success[].key' < file.json
KEY-6555

As Charles Duffy says, jq is not just shorter, but more reliable. A lot of JSON encoders don't guarantee key order -- it can just fall out of what order strings hash into -- so you don't know that id will always come before key. Similarly, the producer changes their settings so there's whitespace in your string, and the sed code fails then too. Use jq or another JSON-aware tool and those things aren't problems.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
1

Since you are using [0-9] in you sed syntax, you will need to use sed -E and so:

sed -En 's/(^.*testIssues":\{"success":\[\{"id":"[0-9]+","key":")(KEY-[0-9]+)(.*$)/\2/p' file

You are matching potentially more than one digit after KEY and so use [0-9]+. Also ensure that you are escaping and {} [] characters.

We split the field into 3 sections designated by the three statements enclosed in () in the sed statement. We then print only the second section specified as specified with \2

Raman Sailopal
  • 12,320
  • 2
  • 11
  • 18