Question: Assuming the following file structure:

```
[topic1]
key1 = "value1"
key2 = "value2"
[topic2]
key1 = "value3"
.
.
.

```

How can I extract value2 from key2 from topic1 to the shell?I'm used to use jq to read json file and get key-value entries but I have no idea to extract the key value in this situation.

Answer: 
all `sed` -

> 
> EDIT - I removed the specificity of which topic needed to follow `topic1`. Now any new `[topic` will end the range, so order shouldn't matter.
> 
> 
> 

```
sed -En '/^\[topic1\]/,/^\[topic/ { /^key2\s*=/ { s/^.*=\s*"([^"]+)".*/\1/; p; } }' 

```

Breakout:

`sed -En` says use extended matching but don't print anything unless requested.

`/^\[topic1\]/,/^\[topic/ { ... }`  

says do the stuff between the braces only between the section headers for topic1 and topic2 (inclusive). 

Within that,  

`/^key2\s*=/ { ... }`
says do the stuff between *these* braces only on the key2 lines.

Then, once you've found the key2 between topic1 and the next topic,  

`s/^.*=\s*"([^"]+)".*/\1/;` says replace the whole line with just the value part between the quotes, and then `p`rint the result.

Formatted:

```
sed -En '
  /^\[topic1\]/,/^\[topic/ {
    /^key2\s*=/ { 
      s/^.*=\s*"([^"]+)".*/\1/;
      p;
    }
  }
'

```

Remove the `;`'s and that will work for non-GNU `sed` as well, I think.
> 
> topics are not ordered, so how to define only one?
> 
> 
> 

Just specify `/^\[/` (the beginning of a following topic) as the second pattern (end) of the address range, e. g.:

```
sed -n '/^\[topic1]/,/^\[/s/key2 = "\(.*\)"/\1/p' file

```