4

I am trying to write a command to grep the number of occurrences in a string, but my string is "ATATAT" and I want to grep "ATAT". I am expecting to get 2 outputs when I use command I get only 1.

echo "ATATAT" |grep -o "ATAT" 

I have tried surrounding the string with ** but still it only matches one pattern.

Inian
  • 62,560
  • 7
  • 92
  • 110

3 Answers3

4

The simplest way - make Python do it for you:

python -c "import re; print(re.findall(r'(?=(ATAT))', 'ATATAT'))"
['ATAT', 'ATAT']
CIsForCookies
  • 10,156
  • 5
  • 36
  • 74
4

The long way with bash:

string="ATATAT"
regex="ATAT"
length="${#string}"
counter=0

for((i=0;i<$length;i++)); do
  [[ "${string:$i}" =~ ^$regex ]] && ((counter++))
done

echo "$counter"

Output:

2
Cyrus
  • 69,405
  • 13
  • 65
  • 117
1

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
Sundeep
  • 19,273
  • 2
  • 19
  • 42
  • can you tell me what is the difference between AT(?=(AT)) and (?=(ATAT)). Also cant we use (?=(ATAT)) with grep please ? – Sherif Negm Jul 22 '19 at 05:29
  • 1
    I am not able to think of any difference `AT(?=(AT))` and `(?=(ATAT))` of importance for the first case, other than changing the command to `rg -oP 'AT(?=(AT))' -r '$0$1'`... for `grep -oP`, we need `AT(?=(AT))` for counting purposes... as far as I know, you cannot achieve the first output using `grep`, you need something like `ripgrep` or Python or something else.. – Sundeep Jul 22 '19 at 05:36