$ 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
Or, more nicely formatted:
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
The awk
program outputs the line number followed by the position of the string on that line. If the string occurs multiple times on the line, multiple lines of output will be produced.
The program uses the index()
function to find the string on the line, and if it's found, prints the position on the line where it is found. It then repeats the process for the rest of the line (using the substr()
function) until no more instances of the string can be found.
In the code, the off
variable keeps track of the offset from the start of the line from which we need to do the next search. The pso
variable contains the position within the substring at offset off
where the string was found.
The string is passed on the command line using -v str='to'
.
Example:
$ 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
to
match inpotato
for example)? – steeldriver Aug 01 '18 at 09:49