O grep permite usar expressões regulares do Perl e, portanto, comporta expressões bastante complexas.
Por exemplo, se quero filtrar por textos como "sequence=123", posso usar:
$grep -Po "sequence=\d+" data.txt
sequence=123
sequence=321
Se eu quiser só os números, posso usar lookbehind:
$grep -Po "(?<=sequence=)\d+" data.txt
123
321
Fica um pouco complicado, mas ainda é possível ler. Entretanto, se seu quiser uma lista das sequencias, não tenho recurso. Se eu quiser filtrar campos distintos e trocar a ordem deles na saída, tampouco há recurso disponível, exceto fazer pipe para um awk.
O que eu realmente gostaria é de poder fazer algo assim:
$grep -P "sequence=(\d+)" -p "$1,"
123,321
Como isso não está disponível, resolvi escrever um pouco de Perl. A solução ficou bastante sucinta e flexível. Inicialmente, eu pretendia chamá-la de pgrep, mas como já há um comando pgrep para procurar processos, acabei por nomeá-la grepp (grep and print).
$grepp
Usage: grepp regex [output] [filename]
$grepp 'sequence=(\d+)' '$1\n' log.txt
20
30
40
$cat log.txt | grepp 'sequence=(\d+)' '$1,'
20,30,40,
$cat log.txt | grepp 'sequence=(\d+)'
sequence=20
sequence=30
sequence=40
$gunzip -c data.log.gz | grepp 'id=(\d+)' '$1,'
150647,160346,150648,160347,160348,150649,
$gunzip -c data.log.gz | grepp 'id=(\d+) val=(\d+)' '$1=$2\n'
150647=7
160346=9
150648=4
160347=5
$grepp 'enabled=(\w+)' '$filename: $1\n' *.ini
abc.ini: true
xyz.ini: false
$grepp 'weight=(\d+) items=(\d+)' '@{[$1*$2]}' data.txt
34
110
$grepp while '$filename($lineno): $_' grepp
grepp(22): while(<$fh>) {
