Question: I want parse something like a section entry in an \*.ini file:

```
line='      [          fdfd fdf         f   ]  '

```

What could be the sed pattern (???) for this line to split the

```
'fdfd fdf         f'

```

out?

So:

```
echo "${line}" | sed -E 's/???/\1/g'

```

How can I describe all chars except `[[:space:]]`, `[` and `]` ? This doesn't work for me: `[^[[:space:]]\[]*` .

Answer: 
When you use the `[[:space:]]` syntax, the outer brackets are normal "match one character from this list" brackets, the same as in `[aeiou]` but the inner brackets are part of `[:space:]` which is an indivisible unit.

So if you wanted to match a single character which either belongs to the `space` class or is an `x` you'd use `[[:space:]x]` or `[x[:space:]]`

When one of the characters you want to match is a `]`, it will terminate the bracketed character list unless you give it some special treatment. You've guessed that you need a backslash somewhere; a good guess but wrong. The way you include a `]` in the list is to put it first. `[ab]c]` is a bracketed list containing the 2 characters `ab`, followed by 2 literal-match characters `c]`, so it matches `"ac]"` or `"bc]"` but `[]abc]` is a bracketed list of the 4 characters `]abc` so it matches `"a"`, `"b"`, `"c"`, or `"]"`.

In a negated list the `]` comes immediately after the `^`.

So putting that all together, the way to match a single char from the set of all chars except the `[:space:]` class and the brackets is:

```
[^][:space:][]

```

The first bracket and the last bracket are a matching pair, even if you think it doesn't look like they should be.
```
$ echo "$line" | sed "s/^.*\[[[:space:]]*\([^]]*[^][:space:]]\)[[:space:]]*\].*$/'\1'/"

```

You can split the pattern into two:

```
$ echo "$line" | sed "s/^.*\[[[:space:]]*/'/; s/[[:space:]]*\].*$/'/"

```

`awk` works too:

```
$ echo "$line" | awk -F' *[[\]] *' -vQ="'" '{print Q$2Q}'

```