Existem variações e limitações em como os regexs são avaliados com base no utilitário que fornece a expressão, os argumentos usados ao chamar o comando, o shell no qual o comando é chamado, entre outros problemas.
Com isso dito, a última seção da regex é o que está bloqueando a correspondência quando eu a uso com o grep; não está listado como opcional, portanto está excedendo a contagem de caracteres (procurando por não letras).
[{0} 01:49:15] $ echo "374355011240344" | grep -Eo "[2-6][0-9]{3}([ -]?)[0-9]{4}([ -]?)[0-9]{4}([ -]?)[0-9]{3,4}([ -]?)[0-9]{0,3}[^a-zA-Z]"
[{1} 01:49:33] $ echo "374355011240344" | grep -Eo "[2-6][0-9]{3}([ -]?)[0-9]{4}([ -]?)[0-9]{4}([ -]?)[0-9]{3,4}([ -]?)[0-9]{0,3}[^a-zA-Z]?"
374355011240344
O seguinte site escreveu o livro sobre regexes de cartão de crédito: regex de cartão de crédito
Esta regex corresponderá a Visa, MC e Amex válidos:
"^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13})$"
O link fornecido mostra como "aumentar" esse regex para cobrir todos os principais CCs. Sua abordagem geral (com a qual eu concordo, pelo que vale a pena), é retirar caracteres estranhos antes da correspondência de padrões - removendo espaços, traços, etc. Pode valer a pena investigar.
Mais alguns sites: