Contando as ocorrências de caracteres em uma árvore do sistema de arquivos

Contando as ocorrências de caracteres em uma árvore do sistema de arquivos

A tarefa era encontrar o número de ocorrências do caracter 'a' em todos os arquivos do diretório (recursivamente).

Meu roteiro foi esse

find . -type f -exec grep -o 'a' {} \; 2>/dev/null | wc -l

mas falhou: obtive o resultado 0, mesmo no meu computador local funcionou.

O que há de errado com esse roteiro? Acho que não é à prova de balas ou algo assim. Como eu poderia torná-lo à prova de balas ou correto?

Responder1

Meu palpite é que a máquina problemática grepnão suporta -o.

Se for esse o caso, sua linha de comando está gerando uma mensagem de erro sempre que findexecs grep. No entanto, com o erro padrão redirecionado para /dev/null, os gritos caem em ouvidos surdos.

wcnão recebe um único byte, resultando em uma contagem de linhas 0, porque grepestá saindo imediatamente.

Tente executar seu pipeline sem um redirecionamento stderr ou com o redirecionamento para um arquivo de log. Se eu estiver correto, você deverá ver uma mensagem de erro por arquivo encontrado por find.

Caso você ache útil, aqui está uma alternativa que não utiliza grep:

find . -type f -exec cat {} \; | tr -cd a | wc -m

Se você suporta a alternativa executiva findmais eficiente :+

find . -type f -exec cat {} + | tr -cd a | wc -m

Responder2

Eu fiz isso:

find "${directory-.}" -type f -print0 | xargs -0 -r cat | grep -F -o 'a' | wc -l

que é praticamente igual ao seu comando e obteve um resultado diferente de zero. Você está no diretório que pensava que estava? E você está realmente procurando por a? Caso contrário, sugiro grep -F(como usei) or fgrep, para procurar uma string fixa em vez de uma regexp.

Você pode simplificar ainda mais com grep -r(grep recursivo):

grep -Fro 'a' "${directory-.} | wc -l

Infelizmente, você não pode grepfazer a contagem, pois grep -o -cconta linhas em vez de ocorrências - considero isso um bug.

informação relacionada