2

I have this JSON String:

{"name":"http://someUrl/ws/someId","id":"someId"}

I just want to get value for "id" key and store it in some variable. I succesfully tried using jq. But due to some constraints, I need to achieve this just by using grep and string matching.

I tried this so far: grep -Po '"id":.*?[^\\]"'; But that is giving "id":"ws-4c906698-03a2-49c3-8b3e-dea829c7fdbe" as output. I just need the id value. Please help

user3681970
  • 1,201
  • 4
  • 19
  • 37
  • Use `grep -Po '(?<="id":")[^"]+'` – Wiktor Stribiżew Aug 18 '17 at 13:26
  • 1
    there's a reason XML and JSON parsers exist: regular expressions are simply not powerful enough to parse them. You should push back on the constraints and ask tell your superiors to let you do your job with the right tools. – glenn jackman Aug 18 '17 at 13:35

2 Answers2

2

See Jshon, it is a command line Json parser for shell script usage.

echo '{"name":"http://someUrl/ws/someId","id":"someId"}' | jshon -e id
"someId"

Just noticed I read past the section stating you needed to use standard tools available, if your admin doesn't allow Jshon it is very likely that the system will have Python available which you could use.

echo '{"name":"http://someUrl/ws/someId","id":"someId"}' | python -c 'import sys, json; print json.load(sys.stdin)["id"]'
someId

Using grep for this is just asking for trouble, I would avoid it and opt for a proper Json parser as above.

Geoffrey
  • 10,843
  • 3
  • 33
  • 46
2

With a PCRE regex, you may use lookarounds. Thus, you need to put "id":" into the positive lookbehind construct, and then match 1 or more chars other than ":

grep -Po '(?<="id":")[^"]+'

where

  • (?<="id":") - requires a "id":" to appear immediately to the left of the current position (but the matched text is not added to the match value) and
  • [^"]+ - matches and adds to the match 1 or more chars other than ".

To get the values with escaped quotes:

grep -Po '(?<="id":")[^"\\]*(?:\\.[^"\\]*)*'

Here, (?<="id":") will still match the position right after "id":" and then the following will get matched:

  • [^"\\]* - zero or more chars other than " and \
  • (?:\\.[^"\\]*)* - zero or more consequent sequences of:
    • \\. - a \ and any char (any escape sequence)
    • [^"\\]* - zero or more chars other than " and \
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • `curl -X POST -d '{"asin":"\"$1\"", "template":"bolt","version":"1d"}' -H "Content-Type: application/json" http://someUrl` Hi Asin i want to get as command line? This is not substituting the asin value. Any idea on this? – user3681970 Aug 18 '17 at 13:48
  • So there can be escaped quotes, right? I added an alternative solution supporting escape sequences. – Wiktor Stribiżew Aug 18 '17 at 13:50
  • Sorry for being unclear. Can you please help on this https://stackoverflow.com/questions/45758557/passed-command-line-argument-in-double-quotes-to-curl ? – user3681970 Aug 18 '17 at 14:01