Muitas vezes encontrei-me concatenando greps para progressivamente encontrar dados e remover as partes redundantes. Algo assim:
grep -Po "\(\d+\)" arquivo.log | grep -Po "\d+"
O primeiro grep extrai números cercados por parênteses e o segundo extrai os parênteses e deixa apenas os dígitos.
Para evitar essa repetição, podemos lançar mão dos operadores de lookaround (lookahead e lookbehind).
grep -Po "(?<=\()\d+(?=\))" arquivo.log
O primeiro, um lookbehind, verifica se a expressão inicia com um parêntese "(?<=\()". O segundo, um lookahead, verifica se a expressão termina com um parêntese "(?=\))".
Esses operadores não consomem o que encontram, então o resultado não aparece na saída do grep. Isso explica também por que o lookbehind precisa ser diferente do lookahead; ele entra em ação quando a expressão regular já passou da posição dele.
Uma funcionalidade interessante seria permitir ao grep produzir uma expressão arbitrária com base nos grupos da expressão regular:
grep -Po "\((\d+)\)" -out "$1" arquivo.log
Equanto isso não acontece, eu posso usar os operadores de lookaround para extrair valores e depois calcular a média usando awk, como no exemplo abaixo.
grep -Po "(?<=\()\d+(?=\))" arquivo.log \
| awk '{ sum += $1 } END { if (NR > 0) print sum / NR }'
Podemos chamar isso de CLI/BI.