De man grep
:
-o, --only-matching
Print only the matched (non‐empty) parts of a matching line, with each such part on a separate output line.
Uma pergunta simples: como imprimir apenas as partes correspondentes (não vazias) de uma linha correspondente, com cada parte na mesma linha de saída?
Aqui está uma maneira de fazer o trabalho com uma linha única Perl:
Explicação:
Outra solução possível usando grep e awk:
Que é:
grep -on foo file --> combine o padrão foo e prefixe cada linha de saída com o número da linha baseado em 1 dentro de seu arquivo de entrada. O mesmo número de linha é repetido no caso de mais de uma correspondência, por exemplo:
ah :
-F ":"
-> considere dois pontos como separador para analisar camposs != $1 || NR==1
--> verifique se a variávels
é diferente do valor do primeiro campo OU se a linha em análise é a primeira. Quando verdadeiro, faça o seguinte:s=$1;
-> variável s pega o valor do primeiro campo (número da linha)if(p){print p};
-> se a variávelp
tiver valor, imprima-ap=$2;
-> variávelp
pega o valor do segundo campo (padrão correspondente)next
-> vá para a próxima iteração e comece a reavaliar a condiçãos != $1 || NR==1
na próxima linha{p=p" "$2;}
-> se a condição na etapa 2 for falsa (quando o número da linha é o mesmo da linha anterior: correspondência múltipla na mesma linha), então a variávelp
assume o valor de si mesma concatenada ao segundo campo (padrão correspondente) da linha em análise (com espaço entre eles).END{print p}
--> ao final, quando todas as linhas forem analisadas, imprima o último valor salvo na variável p.Portanto, no caso acima:
a linha 1 ->
1:foo
é analisada: a condição é verdadeira porqueNR==1
.s
pega o vale1
,p
não é valorizado e portanto não é impresso, p pega o valor foo, vai analisando a 2ª linha.linha 2 -->
1:foo
é analisada: a condição é falsa porque s==$1 (o primeiro campo desta linha é = 1 e a variávels
é1
do passo anterior) e NR==2 (estamos na 2ª linha). Portanto, procedemos fazendo{p=p" "$2;}
, onde a variávelp
assume valor + " " + $2 (que éfoo
), tornando-sefoo foo
a linha 3 -->
3:foo
é analisada: a condição é verdadeira porques!=$1
(de fatos
é1
e o primeiro campo da terceira linha é 3).s
pegue o vale3
,p
é valorizado (foo foo
do passo anterior) e portanto é impresso,p
pegue o valorfoo
, vá analisando a 4ª linhalinha 4 -->
3:foo
é analisada: a condição é falsa porque s==$1 (o primeiro campo deste linha é = 3 e a variávels
é3
do passo anterior) e NR==4 (estamos na 4ª linha). Daí procedemos fazendo{p=p" "$2;}
, onde a variávelp
assume valor + " " + $2 (que éfoo
), tornando-sefoo foo
a linha 5 -->
3:foo
é analisada: a condição é falsa porque s==$1 (o primeiro campo desta linha é = 3 e a variávels
é3
do passo 3) e NR==5 (estamos na 5ª linha). Daí procedemos fazendo{p=p" "$2;}
, onde a variávelp
assume o valor para si (que é 'foo foo' do passo anterior) + " " + $2 (que éfoo
), tornando-sefoo foo foo
END --> não há mais linhas para analisar. Assim, a parte seguinte
END
é executada,{print p}
e a variávelp
(que agora contémfoo foo foo
, da etapa anterior) é impressa.Resultado final: