Repetir partidas de linha inteiras com grep para várias instâncias na mesma linha

1

Um desdobramento de esta pergunta:

Enquanto procuramos pela string "banana" do seguinte arquivo, gostaríamos de 1,2,3 e 7 instâncias de linhas 1,2,3 e 4, respectivamente. O número de saídas do grep deve ser igual ao número de instâncias de correspondência enquanto ainda retorna a linha inteira.

There is one banana here
There are two banana banana here
There are three banana banana banana here
Basically there is no limit to how many banana banana banana banana banana banana banana we can have
In fact we need not have any too!

Nota: Se removermos a restrição de linhas inteiras na saída, temos:

grep -no "banana" tempfile 

que retorna

1:banana
2:banana
2:banana
3:banana
3:banana
3:banana
4:banana
4:banana
4:banana
4:banana
4:banana
4:banana
4:banana

Alguma idéia?

EDIT: Esta é a saída pretendida

1 There is one banana here
2 There are two banana banana here
2 There are two banana banana here
3 There are three banana banana banana here
3 There are three banana banana banana here
3 There are three banana banana banana here
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
    
por Manoj Kumar 20.12.2016 / 20:49

3 respostas

2

grep não tem contador para correspondências, apenas -c contador para linhas que têm a correspondência, mas podemos usar awk para fazer isso. Tanto quanto eu entendo, você deseja imprimir a linha que coincide com x número de vezes com base na quantidade de correspondências. Bem, aqui está:

$ awk '{for(i=1;i<=NF;i++) if($i=="banana") counter++;for(j=1;j<=counter;j++) print NR,$0;counter=0 }' input.txt         
1 There is one banana here
2 There are two banana banana here
2 There are two banana banana here
3 There are three banana banana banana here
3 There are three banana banana banana here
3 There are three banana banana banana here
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have
4 Basically there is no limit to how many banana banana banana banana banana banana banana we can have

A idéia básica aqui é que nós fazemos um loop sobre cada palavra em uma linha e contamos as correspondências. Se houver uma correspondência, incrementamos o contador e usamos esse contador para imprimir a mesma linha em um loop. Finalmente, o contador é reiniciado e o processo é repetido

    
por Sergiy Kolodyazhnyy 20.12.2016 / 21:16
3

Usando o operador de repetição de sequência perl , obtendo o número de repetições avaliando o resultado da correspondência em um contexto escalar:

$ perl -pe '$_ x= (() = /banana/g)' file
There is one banana here
There are two banana banana here
There are two banana banana here
There are three banana banana banana here
There are three banana banana banana here
There are three banana banana banana here
Basically there is no limit to how many banana banana banana banana banana banana banana we can have
Basically there is no limit to how many banana banana banana banana banana banana banana we can have
Basically there is no limit to how many banana banana banana banana banana banana banana we can have
Basically there is no limit to how many banana banana banana banana banana banana banana we can have
Basically there is no limit to how many banana banana banana banana banana banana banana we can have
Basically there is no limit to how many banana banana banana banana banana banana banana we can have
Basically there is no limit to how many banana banana banana banana banana banana banana we can have
    
por steeldriver 20.12.2016 / 21:30
0

Não é muito bonito, mas você pode usar algo como

awk '{print NR, gsub(/banana/, "")' <tempfile

Ele funciona usando o comando awk gsub para substituir o padrão de correspondência (aqui, banana) e retorna o número de vezes que ele realiza a substituição. Em seguida, envia o número da linha de entrada e o número de correspondências

Ou para repetir a linha de entrada várias vezes

awk '{A=$0
b=gsub(/banana/, "")
for (i=1; i<=b; i++) print A
}' <tempfile
    
por Nick Sillito 20.12.2016 / 21:24