Inspired by the Python answer, here's a solution using ripgrep
$ echo 'ATATAT' | rg -oP '(?=(ATAT))' -r '$1'
ATAT
ATAT
$ echo 'ATATXAT' | rg -oP '(?=(ATAT))' -r '$1'
ATAT
$ echo 'ATATATATAT' | rg -oP '(?=(ATAT))' -r '$1'
ATAT
ATAT
ATAT
ATAT
(?=(ATAT))
is a positive lookahead (see also What does this regex mean?), it will check a condition without consuming characters and thus possible to do overlapping matches. -r
option allows to replace the matching portion with something else.
Or, use perl
$ # the if condition is there to prevent empty lines for non-matching input lines
$ echo 'ATATATATAT' | perl -lne 'print join "\n", //g if /(?=(ATAT))/'
ATAT
ATAT
ATAT
ATAT
If you just need the count:
$ echo 'ATATATATAT' | rg -coP '(?=(ATAT))'
4
$ # with GNU grep, if PCRE is available
$ echo 'ATATATATAT' | grep -oP 'AT(?=(AT))' | wc -l
4