segunda-feira, 27 de julho de 2026

Grep com Saída Programável

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>) {
  

Nenhum comentário:

Postar um comentário