7
votes

I am trying to extract a substring after matching a pattern in a string.

Now I can't share my hole file but let's take this example.

From this string:

{"code":"S02A5","name":"18\" Leichtmetallräder Doppelspeiche 397","price":"0","standard":"false"}

I want to extract this substring

18\" Leichtmetallräder Doppelspeiche 397

So far I tried the following :

This matches to many results

grep -oP '(?<="code":".....","name":")[^"]+'

I know that the first char after "name":" is always 1, so I tried to use this in the following command, and the return is 8\ which is not that bad because I can add the 1 afterwards.

grep -oP '(?<="code":".....","name":"1)[^"]+'

The problem is that I can't find a way to retrieve the rest of the substring needed, because there's an extra quotation mark after that backslash.

Any ideas how can I solve this?

2
Please use a tool like jq for handling structured, formatted data like JSON. Using grep to do it is like stirring paint with a screwdriver. - Andy Lester

2 Answers

2
votes

That looks like JSON, use for example jq:

$ jq '.name' file
"18\" Leichtmetallräder Doppelspeiche 397"

or

$ jq -r '.name' file
18" Leichtmetallräder Doppelspeiche 397

Update:

If you need to use grep

$ grep -oP '(?<="name":")(\\"|[^"])+' file
18\" Leichtmetallräder Doppelspeiche 397

Explained:

  • (?<="name":") positive lookbehind preceeded by "name":"
  • followed by \"s or non-quotes

OR:

Maybe it should be:

$ grep -oP '(?<="name":")((?<![^\\]\\)\\"|[^"])+' file

since that would match \" and \\\" but not \\"

0
votes

If you are considering Perl, this should work

/tmp> export data='{"code":"S02A5","name":"18\" Leichtmetallräder Doppelspeiche 397","price":"0","standard":"false"}'
/tmp> echo $data | perl -ne  ' /\"name\":(.+?),/ and print "$1\n" '
"18\" Leichtmetallräder Doppelspeiche 397"
/tmp>