Primeiro, um nitpick: uma string como a*na sintaxe normal do shell é uma glob, que funciona de maneira diferente das expressões regulares.
Em uma visão geral de alto nível, o interpretador de shell (ou seja, bash) expande a string a*para uma lista de todos os nomes de arquivos que correspondem ao padrão a*. Eles então se tornam parte dos parâmetros da linha de comando em uma única instância de grep(para os programadores, todas as palavras expandidas passam como strings separadas para o argvargumento de main). Esse grepcomando único analisa os argumentos da maneira que escolher, e cabe grepa interpretá-los como nomes de arquivo, opções, argumentos de opção, expressões regulares etc. e executar as ações apropriadas. Tudo ocorre sequencialmente (AFAIK nenhuma grepimplementação usa vários threads).
Se você implementar um loop em um script de shell para fazer a mesma coisa, é quase garantido que será mais lento que o processo acima, pelos seguintes motivos. Se você gerar um novo processo grep para cada arquivo, certamente será mais lento devido ao aumento da sobrecarga da criação do processo desnecessariamente. Se você construiu a lista de argumentos no script do shell e usou uma única instância de grep, qualquer coisa que você faça no shell ainda será mais lenta porque os comandos do shell precisam ser interpretados (por bash), o que adiciona uma camada extra de código, e você basta reimplementar o que o bash já estava fazendo mais rápido internamente no código compilado.
Quanto a escrever você mesmo em C, provavelmente é possível obter facilmente um desempenho comparável ao processo descrito no primeiro parágrafo, mas é improvável que você consiga obter um ganho de desempenho suficiente nas implementações grep / bash atuais para justificar o tempo gastos sem investigar otimizações de desempenho específicas da máquina ou sacrificar a portabilidade. Talvez você possa tentar criar uma versão arbitrariamente paralelamente agradável de grep, mas mesmo isso pode não ajudar, pois é mais provável que você esteja vinculado à E / S do que à CPU. A expansão de globos e grep já são "rápidos o suficiente" para a maioria dos propósitos "normais".
globexpressão regular. Grande diferença.