With pcregrep:
pcregrep -rMl '^C.*\nC' .
POSIXly:
find . -type f -exec awk '
FNR==1 {last=0; printed=0; next}
printed {next}
/^C/ {if (last) {print FILENAME; printed=1; nextfile} else last=1; next}
{last=0}' {} +
(though that means reading all the files fully with those awk implementations that don't support nextfile).
With versions of GNU grep up to 2.5.4:
grep -rlP '^C.*\nC' .
appears to work, but it's by accident and it is not guaranteed to work.
Before it was fixed in 2.6 (by this commit), GNU grep had overlooked that the pcre searching function it was using would match on the whole buffer currently processed by grep, causing all sorts of surprising behavior. For instance:
grep -P 'a\s*b'
would match on a file containing:
bla
bla
This would match:
printf '1\n2\n' | grep -P '1\n2'
But this:
(printf '1\n'; sleep 1; printf '2\n') | grep -P '1\n2'
Or:
(yes | head -c 32766; printf '1\n2\n') > file; grep -P '1\n2' file
would not (as the 1\n2\n is across two buffers processed by grep).
That behaviour ended up being documented though:
15- How can I match across lines?
Standard grep cannot do this, as it is fundamentally line-based.
Therefore, merely using the '[:space:]' character class does not
match newlines in the way you might expect. However, if your grep
is compiled with Perl patterns enabled, the Perl 's' modifier
(which makes '.' match newlines) can be used:
printf 'foo\nbar\n' | grep -P '(?s)foo.*?bar'
After it was fixed in 2.6, the documentation was not amended (I once reported it there).
Cin your second example.C?grepversions.