$ awk -v str='to' '{ off=0; while (pos=index(substr($0,off+1),str)) { printf("%d: %d\n", NR, pos+off); off+=length(str)+pos } }' file
1: 1
1: 14
Ou mais bem formatado:
awk -v str='to' '
{
off = 0 # current offset in the line from whence we are searching
while (pos = index(substr($0, off + 1), str)) {
# pos is the position within the substring where the string was found
printf("%d: %d\n", NR, pos + off)
off += length(str) + pos
}
}' file
O programa awk
exibe o número da linha seguido pela posição da string nessa linha. Se a string ocorrer várias vezes na linha, várias linhas de saída serão produzidas.
O programa usa a função index()
para encontrar a string na linha e, se for encontrada, imprime a posição na linha onde é encontrada. Em seguida, ele repete o processo para o restante da linha (usando a função substr()
) até que nenhuma instância da cadeia seja encontrada.
No código, a variável off
mantém o controle do deslocamento desde o início da linha a partir da qual precisamos fazer a próxima pesquisa. A variável pso
contém a posição dentro da substring no deslocamento off
onde a string foi encontrada.
A string é passada na linha de comando usando -v str='to'
.
Exemplo:
$ cat file
To be, or not to be: that is the question:
Whether ‘tis nobler in the mind to suffer
The slings and arrows of outrageous fortune,
Or to take arms against a sea of troubles,
And by opposing end them? To die: to sleep;
No more; and by a sleep to say we end
The heart-ache and the thousand natural shocks
That flesh is heir to, ‘tis a consummation
Devoutly to be wish’d. To die, to sleep;
$ awk -v str='the' '{ off=0; while (pos=index(substr($0,off+1), str)) { printf("%d: %d\n", NR, pos+off); off+=length(str)+pos} }' file
1: 30
2: 4
2: 26
5: 21
7: 20