Você está usando a sintaxe correta em seu primeiro exemplo; o problema é + só é considerado especial ao usar expressões regulares "estendidas". A partir da página man da implementação GNU de grep :
Basic vs Extended Regular Expressions
In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose their special meaning; instead use the backslashed versions \?, \+, \{, \|, \(, and \).
( \? , \+ e \| são extensões GNU não padrão).
Então, você precisa escapar do + (assumindo o GNU grep ou compatível):
$ grep "^[A-Z][A-Z]\+" filename
Use o equivalente \{1,\} padrão do \+ do GNU:
$ grep '^[A-Z][A-Z]\{1,\}' filename
ou até aqui:
$ grep '^[A-Z]\{2,\}' filename
Ou ative as expressões regulares estendidas, passando grep o -E sinalizador ou apenas executando egrep ( egrep é o comando que introduziu essas expressões regulares estendidas no final dos anos 70):
$ grep -E "^[A-Z][A-Z]+" filename
$ egrep "^[A-Z][A-Z]+" filename
Em qualquer caso, todos esses seriam funcionalmente equivalentes a:
$ grep '^[A-Z][A-Z]' filename
Assim, você nem precisa do operador + .
No outro exemplo, você tentou:
$ grep "^[A-Z][A-Z]*" filename
* funciona em expressões regulares básicas, mas corresponde a 0 ou mais vezes, não a 1 ou mais. A solução em sua resposta funciona porque diz "corresponde a um capital, depois a outro capital, a 0 ou mais capitais" . O método na pergunta diz "corresponde a um capital, em seguida, 1 ou mais capitais", que é o mesmo. Você também pode usar {min,max} para especificar exatamente quantos deseja e, se deixar de fora max , permite qualquer número (isso também requer expressões regulares estendidas):
$ egrep "^[A-Z]{2,}"
(como uma observação do histórico, egrep não suportou {min,max} inicialmente (e ainda não faz isso no Solaris 11 /bin/egrep ). \{min,max\} support foi adicionado a grep antes de {min,max} foi adicionado a egrep (que, no caso de egrep , quebrou a compatibilidade com versões anteriores)).