Você pode fazer isso com sed em uma pilha ...
sed '/match$/N
s/\n/&INSERT&/3;t
$n;N;P;D'
Isso inseria INSERT após cada terceira ocorrência não sequencial de match na entrada. É a maneira mais eficiente que eu sei fazer isso com sed porque ele não tenta armazenar todas as linhas que ocorrem entre diferentes matches , nem requer trocas de buffer ou comparações back-ref , mas simplesmente incrementa o único meio de contagem de sed - seu número de linha através de seu ciclo de linha.
Há alguma sobrecarga adicionada, é claro - com cada espaço de padrão de jogo ficando um pouco maior - mas ainda é o mesmo fluxo, e não há back-tracking. É apenas primeiro a entrar, primeiro a sair - o que, na minha opinião, é um método muito adequado para sed . De fato, em vez de voltar para verificar se há uma correspondência, sed pode avançar mais à frente para cada partida. Estou um pouco orgulhosa disso e não sei porque nunca pensei nisso antes.
A versão acima, no entanto, iria apertar repetições até certo ponto, porque funciona apenas uma linha atrás da entrada. E a solução para isso é avançar ainda mais e requer apenas um pouco de complexidade adicional na forma de um loop de curto-circuito b ranch :l abel dentro do loop N;P;D para mantê-lo atualizado.
Funciona assim:
seq 100000| sed -ne':n
s/\n/&\tCheck&\t/5p;t
N;/0000$/bn' -eD
... que, para mim, imprime ...
49995
49996
49997
49998
49999
Check
50000
99995
99996
99997
99998
99999
Check
100000
Veja, para manter a contagem, ele incrementa seu buffer de linha para cada ocorrência de match e insere outra linha em sua janela deslizante no espaço padrão. Dessa forma, tudo o que é necessário para verificar se a correspondência foi encontrada é tentar substituir o caractere de ewline s/// nth \n no espaço padrão. Se isso puder ser feito, encontraremos n matches até o momento, e t est poderá desvincular-nos da iteração atual e limpar o incremento completamente.
No exemplo acima, o buffer é incrementado uma vez para cada padrão de espaço que termina com a string 0000 . Quando 5 desses são encontrados, sed imprime o espaço de padrão atual - e todo o buffer - e limpa o contador.
Para você:
printf DCR\n| tee - - - - - |
sed -e:n -e's/\n/&\tCheck&\t/2;t
$n; N;/DCR$/bn' -eP\;D
DCR
DCR
Check
DCR
DCR
DCR
Check
DCR
Agora, se você quiser marcar apenas a ocorrência nth , também é fácil:
printf DCR\n |
tee - - - - - - - - -|
sed -e:n -e's/\n/&\tCheck&\t/3;te
$n; N;/DCR$/bn' -e'P;D;:e
n;be'
... se você realmente olhar para isso, pode ocorrer a você que nós apenas mal arranhamos a superfície aqui ...
DCR
DCR
DCR
Check
DCR
DCR
DCR
DCR
DCR
DCR
DCR